<?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; networking</title>
	<atom:link href="http://jython.xhaus.com/tag/networking/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>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>Socket shutdown versus socket close on cpython, jython and java.</title>
		<link>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/</link>
		<comments>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 18:16:48 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=65</guid>
		<description><![CDATA[So, here we are again with translating cpython socket semantics to java socket semantics, in order to correctly implement the cpython socket API on jython.
The latest issue is socket shutdown.

Cpython sockets have two separate methods related to terminating a socket connection; the close method and the shutdown method.
Before we get into the difference between the [...]]]></description>
			<content:encoded><![CDATA[<p>So, here we are again with translating cpython socket semantics to java socket semantics, in order to correctly implement the cpython socket API on jython.</p>
<p>The latest issue is <strong>socket shutdown</strong>.<br />
<span id="more-65"></span><br />
<a href="http://docs.python.org/library/socket.html#id1">Cpython sockets</a> have two separate methods related to terminating a socket connection; the <strong>close</strong> method and the <strong>shutdown</strong> method.</p>
<p>Before we get into the difference between the two, we should note that when a TCP socket connection is to be terminated, a network packet containing a FIN is sent to the peer, informing them to tear down the connection (although <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination">sometimes an RST packet can be sent instead</a>). It is a sometimes used practice to <a href="http://www.developerweb.net/forum/showthread.php?t=2940">shutdown only one side of a connection</a>. For example, when a client knows that its request has been fully transmitted, it shuts down its transmit stream to the server, but leaves the receive stream open for the response. This makes the clients intention for future communications more explicit, and may lighten the load on the server. However, this is controversial topic, because that can also lead <a href="/?p=5">asynchronous servers</a> to mistakenly think that a socket is readable when it is not. You can find a detailed and thorough discussion of this topic in ActiveState <a href="http://code.activestate.com/recipes/408997/">Recipe 408997: When to not just use socket.close()</a>; make sure to read all of the comments.</p>
<p>The <strong>close</strong> method of sockets closes the file descriptor to which the socket is connected. When the last file descriptor connected to the socket is closed, then the operating system also closes the underlying socket, which results in the transmission of the FIN packet. That wording is important: <em>&#8220;when the last file descriptor .. is closed&#8221;</em> has specific meaning in many unix network servers architectures. The archetypal design for a network server on unix is to accept incoming socket connections in one process, and then spawn a subprocess to service the connection. Since the child process inherits the file descriptor table of its parent, it also inherits a file descriptor for the socket. Which means that there can be multiple file descriptors open on a socket. Which means that closing a socket is not guaranteed to close the connection; that will not happen until <strong>all</strong> file descriptors for the socket are closed.</p>
<p>The <strong>shutdown</strong> method, on the other hand <strong>only</strong> sends the FIN packet, regardless of how many file descriptors are open to the socket; moreover, it doesn&#8217;t affect any of those file descriptors.</p>
<p>There are some problems for implementing <strong>shutdown</strong> on java and thus on jython. Java servers are almost always multi-threaded, and process incoming requests in spawned threads, <strong>not</strong> processes. For this reason, and because of the fact that java does not expose C file descriptors, there are no socket methods that differentiate between the socket and file descriptor; the two are one and the same in java. This applies to all types of socket.</p>
<p>Implementing shutdown will be discussed below under the different socket types</p>
<ol>
<li><strong>TCP client sockets</strong> are fine: <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html">java.net.Socket</a> objects have the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#shutdownInput()">shutdownInput</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#shutdownOutput()">shutdownOutput</a> methods, which shut down the receive stream and the transmit stream respectively.</li>
<li><strong>TCP server sockets</strong> are different: they don&#8217;t have transmit and receive streams: they exist only to <strong>accept</strong> incoming socket connections. So when a TCP server socket is shutdown, the result of the call should be to close the listen queue for the socket, and discard all queued incoming connections. In java, server sockets do not have a shutdown method (as you can see from their javadocs: <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/ServerSocket.html">java.net.ServerSocket</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/chennels/ServerSocketChannel.html">java.nio.channels.ServerSocketChannels</a>: remember, both classes are required to fully implement all cpython socket semantics in jython). So, how to implement the <strong>shutdown</strong> for TCP server sockets? In java, the same effect is achieved is issuing the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/ServerSocket.html#close()">close</a> method. So the choice is whether or not to make <strong>shutdown</strong> call <strong>close</strong>? Since production code that uses the <strong>shutdown</strong> method will also call the <strong>close</strong> method immediately, or soon afterwards, that would make that series of calls fail. Therefore, the right choice (IMHO) is to have the <strong>shutdown</strong> method as a no-op, i.e. <strong>do nothing</strong>, and document the fact that the user must call <strong>close</strong> on the socket in the <a href="http://wiki.python.org/jython/NewSocketModule">jython socket module documentation. </a></li>
<li><strong>UDP sockets</strong>, similarly don&#8217;t have input and output streams; calling shutdown on the socket should stop the acceptance of incoming packets. But in java, neither <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/DatagramSocket.html">java.net.DatagramSocket</a>s nor <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/DatagramSocket.html">java.nio.channels.DatagramSocketChannel</a>s have <strong>shutdown</strong> methods; instead the same effect is achieved in by calling the <strong>close</strong> method. So, the right choice for the <strong>shutdown</strong> of UDP sockets is to make it a no-op, and document that fact.</li>
</ol>
<p>I have checked in an implementation of the above into the jython SVN; in the release 2.2 maintenance branch at <a href="http://fisheye3.atlassian.com/changelog/jython?cs=6000">revision 6000</a> and into trunk at <a href="http://fisheye3.atlassian.com/changelog/jython?cs=6001">revision 6001</a>. I have put together this page to record my reasoning for implementing things this way, and the research that I&#8217;ve done in trying to arrive at the right implementation. Or at least, an implementation that is <strong>as right as possible</strong> for the jython programmer.</p>
<p>On a related note, I see that the good people over in <a href="http://twistedmatrix.com/">Twisted Matrix</a> are making <a href="http://twistedmatrix.com/trac/ticket/3413">great progress with getting twisted running on jython</a>. It will be fantastic to see one of the premier python <a href="/?p=5">asynchronous frameworks</a> working on jython!</p>
<p>Lastly, thanks to <a href="http://twistedmatrix.com/glyph/">Glyph Lefkowitz</a> of <a href="http://twistedmatrix.com">twisted</a> for reporting this situation in the jython bug tracker: <a href="http://bugs.jython.org/issue1121">listening socket shutdown expects the wrong kind of socket</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/socket-shutdown-versus-socket-close-on-cpython-jython-and-java/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Twisted and Zope: high performance asynchronous network servers in jython.</title>
		<link>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/</link>
		<comments>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 19:10:13 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=5</guid>
		<description><![CDATA[I&#8217;m tremendously excited this week; it looks like the work I did on supporting asynchronous sockets and select in jython has paid off.

Cpython excels in a very specific area; asynchronous (aka non-blocking) network servers. Back in the days before multi-threading was invented, asynchronous designs were the only available mechanism for managing more than one connection [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m tremendously excited this week; it looks like <a href="http://fisheye3.atlassian.com/changelog/jython?cs=3227">the work I did on supporting asynchronous sockets and select in jython</a> has paid off.</p>
<p><span id="more-5"></span></p>
<p>Cpython excels in a very specific area; <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">asynchronous (aka non-blocking) network servers</a>. Back in the days before <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)">multi-threading</a> was invented, asynchronous designs were the only available mechanism for managing more than one connection in a single <a href="http://en.wikipedia.org/wiki/Process_(computing)">process</a>. Although it was possible to spawn off <a href="http://en.wikipedia.org/wiki/Child_process">new processes</a> to service incoming requests, that made <a href="http://en.wikipedia.org/wiki/Inter-process_communication">communicating and sharing</a> information and resources (e.g. database connections) between server components more complex and intractable.</p>
<p>With an asynchronous design, all of the incoming socket connections are managed by a single process. Current socket connections are kept in a simple data structure, such as a list, along with state information relating to the connection, and perhaps a handler, i.e. a piece of code that services the incoming requests. The single process used the unix <a href="http://docs.python.org/lib/module-select.html">select</a> call (or its descendants such as <a href="http://docs.python.org/lib/poll-objects.html">poll</a>) to monitor the state of every connection simultaneously, and then invoking the associated handlers when a network event of interest to them occurred (i.e. following a <a href="http://en.wikipedia.org/wiki/Reactor_pattern">reactor pattern</a>). And therein lies the problem.</p>
<p>When the asynch server calls the handler to service a request, that handler cannot delay before it returns; it must return very quickly, or it holds up the entire server. Returning quickly is easy if you&#8217;re doing trivial processing, e.g. an echo or chat server.  But if you need to connect to a database, or even do something as simple as a DNS lookup, that requires forming another network connection, sending a request packet and waiting for a response. Which means that if your database or DNS library waits until the response arrives, hundreds of milliseconds or even seconds later, then the entire network server is held up, and clients must wait possibly seconds for service; clearly unacceptable. So with asynchronous servers, you must always use libraries that are aware they are operating in an asynchronous environment, are able to surrender control while they are awaiting a network response, and can add themselves to the server <a href="http://en.wikipedia.org/wiki/Reactor_pattern">reactor</a>, so that they can be notified when their response arrives.</p>
<p>While asynchronous architectures thrived in many areas, they proved to be overly complex for the mainstream programming market. Making all libraries asynch-aware, and tracking all of the interactions between them, was complex, difficult to understand, and thus error-prone. <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)">Multi-threading</a> was invented to circumvent these problems. Instead of a single thread of execution controlling network service, separate threads of execution could be created, giving the illusion that there were multiple copies of the server code executing simultaneously, inside the same process, sharing memory, etc. Actually all the threads were running on the same linear processor, and the available <a href="http://en.wikipedia.org/wiki/Preemptive_multitasking#Time_slice">timeslices</a> were divided between them, in much the same way that most modern operating systems timeslice a single processor between multiple processes. The threads would generally run the same instructions, but would have their own program counter and call stack. Threads made programmers lives much easier, since threads could be designed to execute in a linear fashion. If the thread needed to pause at any stage, e.g. to await the response to a network request, it simply suspended itself, and a different thread <a href="http://en.wikipedia.org/wiki/Context_switch">would be selected to be given CPU time</a>. At low cost.</p>
<p>Well, not quite.</p>
<p>There are problem with threads. Threads can have <a href="http://forums.sun.com/thread.jspa?messageID=3803197">very large memory overheads</a>, perhaps measuring in megabytes. Threads must <a href="http://en.wikipedia.org/wiki/Synchronization_(computer_science)">synchronised</a>, so that they don&#8217;t corrupt shared data structures, e.g. <a href="http://en.wikipedia.org/wiki/Race_condition">race conditions</a>, which can be very hard to recognise when they happen, and complex to avoid in design. And threads can <a href="http://en.wikipedia.org/wiki/Deadlock">deadlock</a>, which can be enormously difficult to debug.</p>
<p>The overhead of threads is such that it is rare to see a threading-based server outperform a well designed asynchronous server, on identical hardware. Threaded servers rarely service more than a couple of thousand network connections simultaneously; many can only service in the hundreds per second. There have been incredible increases in all forms of hardware capacity in recent decades; commodity boxes come  with gigahertz processors, gigabytes of memory, terabytes of hard disk, and gigabits of network bandwidth. But although threaded-based servers have vastly improved in design, they still cannot match the performance of asynchronous servers, and address the <a href="http://www.kegel.com/c10k.html">C10K problem</a>.</p>
<p>The C10K problem is a simple one; how to service 10,000 simultaneous network requests. I refer to you the <a href="http://www.kegel.com/c10k.html">C10K website</a> for enormously detailed technical information on this complex problem. Suffice it to say that asynchronous architectures, with their much smaller memory usage, and lack of need for locking, synchronisation and context-switching, are generally considered to be far more performant than threaded architectures.</p>
<p>So where does python come in? It so happens that python is an excellent language for writing asynchronous servers. Python&#8217;s expressiveness and conciseness make it an excellent choice for developing simple and elegant solutions to the problems posed by asynchronous designs. Python was first published in 1991, years before java, and did not develop multi-threading until much later; <a href="http://docs.python.org/lib/module-threading.html">python&#8217;s threading design</a> borrows much from java&#8217;s design. Before threading came to python, asynchronous was the design of choice; none more so than Sam Rushing&#8217;s <a href="http://www.nightmare.com/medusa/">medusa</a>, which is still considered the archetypal asychronous design, and was adapted into python as the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">asyncore module</a>.</p>
<p>But asyncore is basic, and doesn&#8217;t provide non-blocking support for the protocols necessary in a real-world application; database protocols, DNS lookups, etc. But there are two heavyweights in the python asynchronous world that have the required support, in a robust form. <a href="http://www.zope.com">Zope Corporation</a> was there first with their venerable <a href="http://en.wikipedia.org/wiki/Zope">Zope</a> product, arguably the grand-daddy of all python web frameworks. But dissatisfaction with Zope&#8217;s complexity lead to a new initiative; the <a href="http://en.wikipedia.org/wiki/Twisted_(software)">Twisted Matrix</a>. I won&#8217;t try to introduce Twisted here; take a look at the names of the sponsors on the <a href="http://twistedmatrix.com/">Twisted website</a> to see how important a framework it is.</p>
<p>And that&#8217;s why I&#8217;m excited; Twisted could soon be running on jython!</p>
<p>Back in the old days, jython 2.1 could not do aysnchronous socket operations. Jython 2.1 was written in the days when the only socket support in java was <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/package-summary.html">java.net</a>, which was threading oriented. It was only in <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">version 1.4 of the JVM that asynchronous support arrived</a>, in the shape of the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/package-summary.html">java.nio</a> package. Now java has robust asynchronous support, after several years in the field.</p>
<p>I saw the possibility of using java.nio to enable jython to do asynchronous sockets a couple of years ago. I developed the support, and <a href="&lt;a href=">checked it into jython 2.2 last year</a>, in the hope that it would draw the attention of developers of the big cpython asynchronous frameworks. Java has some distinct advantages over cpython in high performance network serving world, with the most obvious being the ability to run on all cores of <a href="http://en.wikipedia.org/wiki/Multi-core_(computing)">multi-core processors</a> simultaneously. Cpython is restricted in this regard by it&#8217;s <a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock">Global Interpreter Lock</a>, which prevents multiple threads running pure python code from running on multiple cores or processors simultanously. In java, and thus in jython, every single core in the multi-core system can be running its own reactor, actually simultaneously.</p>
<p>It&#8217;s looking more like those cpython asynchronous frameworks could be coming to jython soon.</p>
<p>The founder and chief architect of Twisted, <a href="http://glyph.twistedmatrix.com/">Glyph Lefkowitz</a>, logged three bugs (<a href="http://bugs.jython.org/issue1119">1119</a>, <a href="http://bugs.jython.org/issue1120">1120</a>, <a href="http://bugs.jython.org/issue1121">1121</a>) against the jython socket module last week; I fixed them yesterday. I&#8217;m glad to say that they were all relating to corner cases and unusual usage; so far there have been no reports of serious bugs in the main functionality of the socket module. So hopefully the road to running twisted on jython is clear and obstacle free, at least at the level of socket communications.</p>
<p>And the Zope people have an ongoing project to get Zope running on jython; see the <a href="http://www.nabble.com/forum/Search.jtp?query=jython&amp;sort=date&amp;local=y&amp;forum=6720">Zope-dev archives</a> for ongoing updates.</p>
<p>Yes, exciting times indeed!</p>
<p>If you are interested in reading further about asynchronous I/O in the java.nio package, I thoroughly recommend Ron Hitchens book <a href="http://javanio.info">Java NIO</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/twisted-and-zope-high-performance-asynchronous-network-servers-in-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing an all-trusting security provider on java and jython.</title>
		<link>http://jython.xhaus.com/installing-an-all-trusting-security-provider-on-java-and-jython/</link>
		<comments>http://jython.xhaus.com/installing-an-all-trusting-security-provider-on-java-and-jython/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 16:38:00 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=4</guid>
		<description><![CDATA[Back in 2007, I updated the jython socket module to support client-side ssl sockets. This post will describe how to configure jython so that it behaves like cpython, in relation to acceptance of SSL certificates.

The support was very basic, because it is an implementation of the existing core cpython ssl socket support, which is really [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2007, <a title="Jython Changeset 3227" href="http://fisheye3.atlassian.com/changelog/jython?cs=3227" target="_self">I updated the jython socket module to support client-side ssl sockets</a>. This post will describe how to configure jython so that it behaves like cpython, in relation to acceptance of SSL certificates.</p>
<p><span id="more-4"></span></p>
<p>The support was very basic, because it is an implementation of the existing <a title="Link to cpython SSL socket documentation" href="http://www.python.org/doc/lib/ssl-objects.html">core cpython ssl socket support</a>, which is really basic, merely allowing a client to make an SSL connection to a server. Cpython has no server-side SSL support in the standard library (although multiple 3rd party modules do support it), and it has no support for certificate management or verification. So basically the cpython ssl support is really only useful for testing; without certificate verification, it&#8217;s not really usable in scenarios where authentication actually matters, e.g. E-commerce.</p>
<p>Because the jython socket module is layered on top of java socket libraries, it automatically inherits java behaviour in relation to certificate validation; <strong>java by default always validates certificates</strong>.</p>
<p>Which is great, if you want certificate validation; it means that you can use the jython ssl support when counterparty authentication actually matters, because it will always verify that the server certificate is valid, and will refuse to form a connection if the certificate is not valid.</p>
<p>However, this is problematic for jython users who want to use the jython ssl support like they would use the cpython ssl support: for testing. In testing phases, it&#8217;s very common for users to create and test with their own <a title="Self signed certificates" href="http://en.wikipedia.org/wiki/Self-signed_certificate">self-signed certificates</a>; installing real production certificates may be difficult for a number of operational reasons.</p>
<p>As described above, this is not a problem for cpython users. But jython users have to go an extra step in order to be able to use self-signed certificates. There are two choices</p>
<ol>
<li>Add the self signed certificate to the JVM configuration. To do that, read this <a title="Installing and Configuring SSL Support " href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security6.html">Sun article on Installing and Configuring SSL Support</a>.</li>
<li>Install a custom java Security Provider which simply trusts all certificates. <strong>WARNING: Installing a security provider that accepts all certificates leaves you open to all forms of impersonation and other identity-verification failures; only use it for testing purposes!</strong> To install a custom security provider requires writing some java. I&#8217;ll explain it below.</li>
</ol>
<p>In order to change the Java trust decision process, you have to create an <a title="Link to X509TrustManager documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/X509TrustManager.html">X509TrustManager</a>. Java TrustManagers are based on an exception model; the trust manager is called to determine if a given client, server or issuer is trusted. If not, the TrustManager should raise a <a title="Link to CertificateException documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/CertificateException.html">CertificateException</a>. Which means that if a TrustManager wishes to trust everyone, it simply should not raise exceptions when a trust request is made.</p>
<p>But you can&#8217;t just create and install a TrustManager; TrustManagers are created by a <a title="Link to TrustManagerFactory documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/TrustManagerFactory.html">TrustManagerFactory</a>, so you have to create and install one of those. And in order to do that, you have to create and install a <a title="Link to java.security.Provider documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/java/security/Provider.html">java.security.Provider</a>. Sounds complex? </p>
<p>Well, thankfully it&#8217;s not that complex, as you can see in the code sample from this article on the ZXTC KnowledgeHub: <a title="Link to article containing source code to install a new java.security.Provider" href="http://knowledgehub.zeus.com/articles/2006/01/03/using_the_control_api_with_java">Using the Control API with Java.</a> I have reproduced that code here.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">&nbsp;
<span style="color: #666666; font-style: italic;">// Example java.security.Provider implementation</span>
<span style="color: #666666; font-style: italic;">// that trusts ALL SSL certificates</span>
<span style="color: #666666; font-style: italic;">// Regardless of whether they are valid or not</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Store this code in a file called MyProvider.java</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.Security</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.KeyStore</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.Provider</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.cert.X509Certificate</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.net.ssl.ManagerFactoryParameters</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.net.ssl.TrustManager</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.net.ssl.TrustManagerFactorySpi</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.net.ssl.X509TrustManager</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyProvider <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Provider</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> MyProvider<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;MyProvider&quot;</span>, <span style="color: #cc66cc;">1.0</span>, <span style="color: #0000ff;">&quot;Trust certificates&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    put<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;TrustManagerFactory.TrustAllCertificates&quot;</span>, MyTrustManagerFactory.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> MyTrustManagerFactory <span style="color: #000000; font-weight: bold;">extends</span> TrustManagerFactorySpi
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> MyTrustManagerFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> engineInit<span style="color: #009900;">&#40;</span> <span style="color: #003399;">KeyStore</span> keystore <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> engineInit<span style="color: #009900;">&#40;</span>ManagerFactoryParameters mgrparams <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> TrustManager<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> engineGetTrustManagers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> TrustManager<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #000000; font-weight: bold;">new</span> MyX509TrustManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> MyX509TrustManager <span style="color: #000000; font-weight: bold;">implements</span> X509TrustManager
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> checkClientTrusted<span style="color: #009900;">&#40;</span><span style="color: #003399;">X509Certificate</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> chain, <span style="color: #003399;">String</span> authType<span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> checkServerTrusted<span style="color: #009900;">&#40;</span><span style="color: #003399;">X509Certificate</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> chain, <span style="color: #003399;">String</span> authType<span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">X509Certificate</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getAcceptedIssuers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This class should be stored in a file called MyProvider.java, and compiled with javac to generate a MyProvider.class file, which you should place in the classpath.</p>
<p>Once that&#8217;s complete, execute the following piece of jython</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">java.<span style="color: black;">security</span>.<span style="color: black;">Security</span>.<span style="color: black;">addProvider</span><span style="color: black;">&#40;</span>MyProvider<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
java.<span style="color: black;">security</span>.<span style="color: black;">Security</span>.<span style="color: black;">setProperty</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ssl.TrustManagerFactory.algorithm&quot;</span>, <span style="color: #483d8b;">&quot;TrustAllCertificates&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></pre></div></div>

<p>And your code should now start accepting all SSL certificates, regardless of whether they are valid or not.</p>
<p>This issue came up on jython-users, where a jython user was wondering why, after he had installed his own TrustManagerFactory, he could access an HTTPS url on a server with an invalid certificate, without problems, when using <a title="Link to java.net.URL exception" href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URL.html">java.net.URL</a>.</p>
<p>But when he tried to use jython&#8217;s <a title="Link to urllib2 documentation" href="http://docs.python.org/lib/module-urllib2.html">urllib2</a>, it failed with a <a title="Link to CertPathValidatorException documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/CertPathValidatorException.html">java.security.cert.CertPathValidatorException</a>. The reason for that is that the jython urllib2 module does not use java.net.URL; it uses the jython socket module directly. So over-riding the default TrustManagerFactory for the <a title="Link to javax.net.ssl.HttpsURLConnection documentation" href="http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/HttpsURLConnection.html">javax.net.ssl.HttpsURLConnection</a> class has no effect on anything but instances of the HttpsURLConnection class. Which happens to be the class that java.net.URL uses to make HTTPS connections.</p>
<p>Read the jython-users post <a title="Link to jython-users post about invalid certs." href="http://www.nabble.com/https---invalid-certs-td19198649.html">HTTPS and invalid certs</a> for more details.</p>
<p>Lastly, this information is reproduced on the <a title="Link to jython wiki documentation for the socket module." href="http://wiki.python.org/jython/NewSocketModule">Jython Socket Module Wiki page</a>, which I try to keep up-to-date as much as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/installing-an-all-trusting-security-provider-on-java-and-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Timeout sockets for jython</title>
		<link>http://jython.xhaus.com/timeout-sockets-for-jython/</link>
		<comments>http://jython.xhaus.com/timeout-sockets-for-jython/#comments</comments>
		<pubDate>Fri, 03 Jun 2005 10:00:14 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=101</guid>
		<description><![CDATA[Back in 2005, I modified the jython socket module to support timeouts. Brian Zimmer checked in that patch, since I did not have jython SVN commit rights at that time.
I wrote a documentation page about the new timeout support, and placed it on xhaus.com. Due to a rearrangement of the xhaus.com website, I am moving [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2005, I modified the jython socket module to support timeouts. Brian Zimmer <a href="http://fisheye3.atlassian.com/changelog/~author=bzimmer/jython/?cs=2501">checked in that patch</a>, since I did not have jython SVN commit rights at that time.</p>
<p>I wrote a documentation page about the new timeout support, and placed it on xhaus.com. Due to a rearrangement of the xhaus.com website, I am moving that page to this blog.</p>
<p>It should be noted that the timeout functionality has been superceded by the further <a href="http://fisheye3.atlassian.com/changelog/~author=amak/jython/?cs=3227">work that I did to make the socket module support asychronous I/O</a>. So you should refer to the <a href="http://wiki.python.org/jython/NewSocketModule">jython socket module documentation</a> to see how to use timeouts. This page appears here solely for historical purposes.</p>
<p><span id="more-101"></span></p>
<hr/>
<h2>Introduction</h2>
<p>
		Socket timeouts are now included in the jython 2.2 distribution! So the information on this page is now out of date; you should <a href="http://www.jython.org/Project/download.html">download the latest release of jython</a> instead.
	</p>
<p>
	Sockets are the core technology that enable inter-machine communications on the Internet. They generally do a pretty excellent job of communicating information across the globe, and are generally straightforward to use in software. But sometimes networks are saturated or servers are overloaded, which means that code using sockets has to be aware that socket connections can break, or can timeout, meaning that replies were not received from a remote party before a specified time had elapsed.
	</p>
<p>
	Writing robust network software can be made much easier when a language supports detection of timeouts on sockets. The purpose of this page is to describe some modifications I&#8217;ve made to the standard jython socket module to support socket timeouts.
	</p>
<p>
	You can read below about the history of socket timeouts in cpython, java and jython.
	</p>
<h2>How to get the code</h2>
<p>
	To use timeouts, simply
	</p>
<ol>
<li>Download <a href="http://cvs.sourceforge.net/viewcvs.py/jython/jython/Lib/socket.py?rev=1.16&amp;view=log">CVS version 1.16 of the socket.py module</a>. </li>
<li>Replace the $jython_home/Lib/socket.py module with the new one just downloaded. </li>
</ol>
<p>
	The source was originally made available as a <a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1210830&amp;group_id=12867&amp;atid=312867">patch</a> against <a href="http://cvs.sourceforge.net/viewcvs.py/jython/jython/Lib/socket.py?rev=1.15&amp;view=log">version 1.15</a> of the socket module.
	</p>
<h2>Documentation</h2>
<p>
		The API implemented should be identical to the cpython 2.3 API, so you should use the <a href="http://www.python.org/doc/2.3.5/lib/module-socket.html">cpython 2.3 socket module documentation</a>. In most cases, you should get identical behaviour from the same code run on both platforms. This includes the <b>socket.timeout</b> exception, which is defined as a subclass of the <b>socket.error</b> exception.
	</p>
<p>
		However, see below for one important difference between cpython and jython: <a href="#zero">the treatment of a zero timeout value</a>.
	</p>
<h2>Testing</h2>
<p>
	I have also provided a module of unit-tests for the new timeout functionality. This module is derived mostly from the <a href="http://cvs.sourceforge.net/viewcvs.py/python/python/dist/src/Lib/test/test_socket.py?only_with_tag=release23-branch">socket test module from cpython 2.3</a>: I copied a lot of that code, and added a couple of new tests.
	</p>
<p>
	The test module is designed to run on both cpython (2.3+ only) and jython, and should ideally give identical results on both platforms. However, there is one of the tests (<b>testTimeoutZero</b>), that will fail on cpython, because of the <a href="#zero">problem with zero timeouts</a>.
	</p>
<p><a name="zero"></a></p>
<h2>Differences in the treatment of zero timeout values</h2>
<p>
	On cpython, when you specify a zero (i.e. 0 or 0.0) timeout value, the socket should behave the same as if the socket had been placed in <b>non-blocking</b> mode. See the <a href="http://www.python.org/doc/2.3.5/lib/socket-objects.html">cpython 2.3 socket object documentation</a> for details.
	</p>
<p>
	Unfortunately, it is not possible to support non-blocking mode on sockets in java versions prior to 1.4. Moreover, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#setSoTimeout(int)">java interprets a zero timeout value as an infinite timeout</a>, i.e. the socket is placed in <b>blocking</b> mode.
	</p>
<p>
	To solve this conflict, I decided that the best thing to do with zero timeouts is to adjust them to the smallest possible timeout in java, which is 1 millisecond. So if you do <b>socket.settimeout(0)</b> with this module, what you will really get is equivalent to the cpython call <b>socket.settimeout(0.001)</b>.
	</p>
<p>
	This means that you may get differing exception signatures when using zero timeouts under cpython and jython.
	</p>
<ol>
<li><b>Cpython</b>: socket operations with zero timeouts that fail will raise <b>socket.error</b> exceptions. This is equivalent to a -1 return from the <a href="http://www.rt.com/man/recv.2.html">C socket.recv</a> call, with errno set to EAGAIN, meaning &quot;<i>The  socket is marked non-blocking and the receive operation would block, or a  receive  timeout  had been  set and the timeout expired before data was received.</i>&quot;</li>
<li><b>Jython</b>: socket operations with zero timeouts that fail will generate <b>socket.timeout</b> exceptions.</li>
</ol>
<h2>History of socket timeouts in python &amp; java</h2>
<h3>Timeouts in cpython</h3>
<p>
	A socket timeout API was only introduced in Cpython version 2.3. Prior to that, the only way to implement socket timeouts was to use the <a href="http://www.python.org/doc/2.3/lib/module-select.html">select system call</a>, a technique which was used by <a href="http://py.vaults.ca/apyllo.py/812237977.116898894.87800233">Tim O Malley&#8217;s timeoutsocket.py</a>
	</p>
<h3>Timeouts in java</h3>
<p>
	Java has supported socket timeouts since JDK version 1.1, when the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#getSoTimeout()">getSoTimeout()</a> and <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#setSoTimeout(int)">setSoTimeout()</a> methods were added to <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html">java.net.Socket</a> objects.
	</p>
<p>
	However, Java could not support non-blocking I/O until JVM 1.4, which introduced the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/package-summary.html">java.nio package</a>.
	</p>
<h3>Timeouts in jython</h3>
<p>
	Although Java has been capable of supporting socket timeouts since JDK 1.1, this feature was never added to released versions of jython, since the most recent version of jython released is jython 2.1. Because socket timeouts were only introduced into cpython in version 2.3, there was no cpython 2.1 API for jython 2.1 to copy or implement. The code that I have provided implements the cpython 2.3 socket timeout API.
	</p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/timeout-sockets-for-jython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: Overview</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:30:57 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=107</guid>
		<description><![CDATA[Over the Christmas holidays in 2003, I wrote a design for how Asynchronous Socket I/O might be implemented in jython, using java.nio. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O [...]]]></description>
			<content:encoded><![CDATA[<p xmlns:date="http://exslt.org/dates-and-times">Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O for jython sockets, which is now a part of the jython distribution.</p>
<p>Although these notes are now out-of-date, having been surpassed by the actual implementation itself, I am publishing them here for historical purposes. The notes are broken down into four main areas.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-107"></span><br />
<hr /><a name="intro"></a><br />
<h2>Introduction</h2>
<p>
				The purpose of this document is to discuss the implementation of socket timeouts and asynchronous socket I/O processing in jython.
			</p>
<p>
				In versions of the java language prior to 1.4, java had no built in support for <b>non-blocking</b> I/O. This applied to all forms of I/O, including files, sockets, pipes, etc. This has meant that all I/O involved the use of blocking calls, which consequently required the use of <b>thread</b>s. While threads are a useful abstraction for programmers that permits the processing of multiple requests simultaneously, this abstraction comes at a high cost, in terms of resource consumption. High consumption of resources leads to fundamental limits on the number of requests that can be processed at a time, which means that thread-based architectures can scale badly, and perhaps fail to take advantage of the capabilities of modern PC hardware. For a more detailed discussion of this topic, read about the <a href="http://www.kegel.com/c10k.html">C10K problem</a>. For more information about processing sockets in an asynchronous fashion, read this <a href="http://squirl.nightmare.com/medusa/async_sockets.html">tutorial on Asynchronous Socket Programming</a>.
			</p>
<p>
				In contrast, cpython has had inbuilt support for non-blocking I/O for a long time, based on the C/unix <b>select</b> call, which allows the programmer to examine the readiness state of multiple file descriptors (the unix abstraction which represents all I/O channels). This non-blocking I/O support has enabled cpython to support development of server and client architectures that do not suffer from the limitations of threads, and to process large numbers of requests in a highly stable fashion. Among the cpython frameworks based on non-blocking I/O are
			</p>
<ul>
<li>
<a href="http://www.twistedmatrix.com">Twisted</a>
</li>
<li>
<a href="http://www.nightmare.com/medusa/index.html">Medusa</a>
</li>
<li>
<a href="http://www.python.org/doc/current/lib/module-asyncore.html">Asyncore</a> (library module)</li>
</ul>
<p>
				Prior to version 1.4, java did not provide support for non-blocking socket I/O, therefore it was not possible to provide such support in jython. In version 1.4, java evolved the capability of using I/O channels in a non-blocking manner. This means that it is now possible to implement non-blocking I/O in jython, in a manner that is compatible with cpython. The purpose of these documents is to discuss the implementation of such facilities.
			</p>
<p>
				Also, since version 2.3, cpython has had support for <b>socket timeouts</b>. However, support does not currently exist in jython for socket timeouts, since at the time that the existing jython module was written (version 2.1), timeouts were not a part of the standard interface of sockets. The java platform has always had support for socket timeouts, even in version prior to java 1.4. If modifications are to made to the existing jython socket module to support non-blocking I/O, now is the ideal opportunity to update the socket module to support timeouts as well. As will be discussed, there is a fundamental relationship between non-blocking socket I/O and socket timeouts, in the cpython model at least.
			</p>
<hr /><a name="goals"></a><br />
<h2>Goals for this implementation project</h2>
<p>
				The following are goals for this implementation of non-blocking I/O in jython.
			</p>
<ol>
<li>
<b>Cpython compatibility</b>. The primary requirement is that the developed software be interface-compatible with the cpython library modules which provide socket support. This so that the existing large volume of cpython code which uses sockets can be executed in jython with no modification.</li>
<li>
<b>Thread-safe</b>. The developed software must be <b>thread-safe</b>, i.e. as far as is possible, accessing objects (created through the software) from multiple threads simultaneously must result in predictable behaviour and no corruption of data.</li>
<li>
<b>Non-blocking TCP socket support</b>. The developed software should support nonblocking access to both client and server TCP sockets. This applies to all operations, including opening and closing connections to socket endpoints, reading and writing data, and detection of <b>out-of-band</b> data.</li>
<li>
<b>Non-blocking UDP socket support</b>. Ideally, non-blocking operations should be supported on UDP/datagram sockets.</li>
<li>
<b>Socket timeout support</b>. In cpython 2.3, socket objects gained two new methods: the <b>settimeout</b> and <b>setblocking</b> methods. Although the language features to implement these capabilities for jython sockets have always been available on the Java platform, the current jython socket implementation does not support thse methods (since they were not a standard part of the cpython socket API when the jython module was first written). Although the primary goals of this project are to support nonblocking I/O, it would also be desirable to implement these methods for all versions of java prior to 1.4, so that jythonistas can at least have an API which is as compatible as possible with cpython 2.3, even if they are using a pre1.4 JVM.</li>
</ol>
<p>
				The following are <b>not</b> goals of this project.
			</p>
<ol>
<li>
<b>Non-blocking file operation support</b>. Ideally, in order to support the development of high-throughput and robust server architectures, the developed software should provide support for non-blocking operations on files and directories.</li>
<li>
<b>Non-blocking pipe operation support</b>. Ideally, the developed software should provide support for non-blocking operations on pipe, i.e. communications channels between OS processes.</li>
<li>
<b>Non-blocking generic I/O support</b>. Ideally, the developed software should provide support for non-blocking operations on any form of I/O channel, i.e. any communications channel that supports transmission and receipt of a stream of bytes.</li>
</ol>
<p>
				However, it is currently not possible to provide support for these desirable features, in a platform independent fashion, since java 1.4 does not support non-blocking operations on I/O channels other than sockets. While it is possible to provide support in a platform-dependent fashion, using JNI, such an implementation is outside the scope of this project.
			</p>
<hr /><a name="language"></a><br />
<h2>Java vs. jython</h2>
<p>
                There are two choices for the language in which this software can be implemented.
            </p>
<table border="1">
<tr>
<th>Language</th>
<th>Pros</th>
<th>Cons</th>
</tr>
<tr>
<td><b>Java</b></td>
<td>
<ol>
<li>Speed. If the software is written in Java, it will be faster, since a layer of jython interpretation will be avoided.</li>
<li>More robust exception handling: java&#8217;s insistence on explicit declaration and handling of exceptions means that exceptions are less likely to go unforeseen or unprocessed.</li>
</ol>
</td>
<td>
<ol>
<li>Changing object model in jython. As noted by Samuele Pedroni, the interface to the java implementation of jython classes may change in the near future, which would require a rewrite for future versions of jython. (Presumably this is because of the requirement to support python 2.2 new-style classes and metaclasses).</li>
<li>Lengthier implementation.</li>
</ol>
</td>
</tr>
<tr>
<td><b>Jython</b></td>
<td>
<ol>
<li>More flexibility in prototyping multiple approaches.</li>
<li>More flexibility when building, thus more likely end up with running software.</li>
<li>Less lines of code means less bugs.</li>
<li>Can be readily translated to java in the future.</li>
</ol>
</td>
<td>
<ol>
<li>Slight loss of execution speed.</li>
</ol>
</td>
</tr>
</table>
<p>
                It is proposed to implement this software in jython.
            </p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the socket module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:10:59 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=112</guid>
		<description><![CDATA[Over the Christmas holidays in 2003, I wrote a design for how Asynchronous Socket I/O might be implemented in jython, using java.nio. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O for jython sockets, which is now a part of the jython distribution.</p>
<p>Although these notes are now out-of-date, having been surpassed by the actual implementation itself, I am publishing them here for historical purposes. The notes are broken down into four main areas.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-112"></span><br />
<hr /><a name="intro"></a><br />
<h2>Modifications to the existing jython socket module</h2>
<p>
				There are a number of modifications that would need to be made to the existing jython socket implementation in order to facilitate support for timeouts and for non-blocking operations. These modifications are discussed in this document.
			</p>
<hr /><a name="socketvschannel"></a><br />
<h2>Socket objects vs. SocketChannel objects</h2>
<p>
                It is required to provide a facility in jython which permits the programmer to &#8220;watch&#8221; the readiness status of multiple I/O channels. In cpython, file descriptors are the handles which are used to represent watchable channels. A typical code sequence might look like this
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
fd = s.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
po = <span style="color: #dc143c;">select</span>.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
po.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span></pre></div></div>

<p>
                However, the concept of a file descriptor has no meaning on the java platform, since the JVM does not use file descriptors (they are too platform specific). Instead, in a jython implementation, it will be necessary to obtain a <b>java.nio.channels.SelectableChannel</b> representing the channel to be watched.
            </p>
<p>
                Fortunately, all socket objects in the <b>java.net</b> package have a <b>getChannel()</b> method (as of java 1.4 anyway).</p>
<p>
             	Unfortunately, this method returns a <b>null</b> value when used with a socket created by the constructors <b>java.net.Socket</b>, <b>java.net.ServerSocket</b>, <b>java.net.DatagramSocket</b>. The only time when <b>java.net.*Socket.getChannel()</b> returns a SelectableChannel is when the socket itself was created through  the <b>java.nio.channels</b> package. In all cases, this is done by calling a static method of the relevant class. The creation methods for the different channel types are
            </p>
<table border="1">
<tr>
<th>Channel type</th>
<th>Java.net constructor</th>
<th>Java.nio construction method</th>
</tr>
<tr class="tabodd">
<td>TCP Client Socket</td>
<td>java.net.Socket()</td>
<td>java.nio.channels.SocketChannel.open()</td>
</tr>
<tr class="tabeven">
<td>TCP Server Socket</td>
<td>java.net.ServerSocket()</td>
<td>java.nio.channels.ServerSocketChannel.open()</td>
</tr>
<tr class="tabodd">
<td>UDP Socket</td>
<td>java.net.DatagramSocket()</td>
<td>java.nio.channels.DatagramChannel.open()</td>
</tr>
</table>
<p>
                This restriction means that all sockets that are to be processed using this proposed non-blocking socket I/O API must be created through the java.nio construction method outlined above.
            </p>
<p>
            	However, it is not simply of case of switching over to the new methods for all socket creation, since it is hoped to also support as many operations as possible on JVMs prior to version 1.4, e.g. timeouts. Therefore, it is necessary to separate out socket creation operations to a single set of factory methods or functions, which can be altered depending on the runtime environment in which they are run. The following is one proposed code sequence for creating socket factory functions, which should work on all JVMs. Another possible approach might be to create a factory class which dynamically modifies its behaviour.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;using java.nio&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SocketChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createserversock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">ServerSocketChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createdatagramsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">DatagramChannel</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;using java.net&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">Socket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createserversock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">ServerSocket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _createdatagramsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> java.<span style="color: black;">net</span>.<span style="color: black;">DatagramSocket</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note that it should be sufficient to return simple <b>java.net</b> socket objects from these functions, because
			</p>
<ol>
<li>It requires less code modification to the existing jython socket module: the existing code is designed to work with <b>java.net.*Socket</b> objects.</li>
<li>In the case of 1.4 JVMs, where support for non-blocking operations is provided, the SelectableChannel corresponding to a socket can always be retrieved from the socket&#8217;s <b>getChannel()</b> method.</li>
<li>In the case of pre-1.4 JVMs, which do not support nonblocking I/O, calls to the <b>getChannel()</b> method will fail. However, non-blocking support is not provided for pre-1.4 JVMs.</li>
</ol>
<p>
				In summary
            </p>
<ol>
<li>Sockets should be created using the java.nio APIs where possible</li>
<li>Sockets should be created using the java.et APIs if java.nio is not available</li>
<li>Both these factory methods should return objects which implement the same interface, i.e. the interface presented by socket objects in the java.net package.</li>
<li>When a java.nio.channels.SelectableChannel is required, it can be retrieved from the socket using the the <b>getChannel()</b> method.</li>
</ol>
<hr /><a name="socketcreation"></a><br />
<h2>Socket creation in existing jython socket module</h2>
<p>
                The existing jython socket module constructs all sockets by using constructors from the <b>java.net</b> package. However, as discussed above, if a socket channel is to be watchable, a java.nio.channels.SelectableChannel object is required. Thus, the existing jython socket module will have to be modified to use the the factory approach outlined above, which uses java.nio where possible, and java.net where not. The only parts of the socket module that should require modification are the parts that actually create sockets.
            </p>
<p>
            For example, the following is the current code for the connect method of socket objects
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
     <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
         addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
     <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
     host, port = addr
     <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
         host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">Socket</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                Which could be replaced with code similar to the following
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
     <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
         addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
     <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
     host, port = addr
     <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
         host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     sock = _createclientsocket<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>sock<span style="color: black;">&#41;</span>
     <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">InetSocketAddress</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note that this code is not yet sufficient: there is still timeout and blocking configuration to be taken into account. See below under <a href="#newmethods">Implementing the cpython 2.3 blocking/timeout model</a>.
			</p>
<hr /><a name="watchabletypes"></a><br />
<h2>Types of channels that can be examined</h2>
<p>
                In cpython, when a channel is to be watched, the <b>file descriptor</b> representing the channel is registered with a <a href="http://www.python.org/doc/current/lib/poll-objects.html">poll object</a>. However, whether or not the channel is <b>watchable</b> is determined by the operating system, and is thus platform independent. This model fits very well with cpython&#8217;s late-binding ethos.
            </p>
<p>
                In contrast, java has a very precise object model which differentiates watchable channels from other channel types by having watchable channel types extend the abstract class <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html">java.nio.channels.SelectableChannel</a>. If a java object is not a subclass of this abstract class, it cannot be &#8220;watched&#8221;.
            </p>
<p>
				This means that a mechanism is required for obtaining the underlying SelectableChannel from any given socket, through a public method, preferably re-using a known and comparable method from the cpython 2.3 API.
            </p>
<p>
                It is proposed to use the (currently unimplemented in jython) <b>fileno()</b> method to enable the programmer to obtain a <b>SelectableChannel</b> object which can be passed to poll objects. The fileno() method is the closest analogy to a SelectableChannel in the cpython model, and its return value is most frequently used as a SelectableChannel would be. However, since the two concepts are different, it is proposed to create two separate methods with the same interface. Thus, the fileno method for sockets could be defined as follows in the jython socket module.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> _tcpsocket:
 <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> getchannel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">getChannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    fileno = getchannel</pre></div></div>

<p>
				The <b>getchannel()</b> method could be used internally to the new jython socket module, since it has inherent knowledge that the returned value is not a file descriptor but a SelectableChannel.
			</p>
<p>
				A similar method would be required for the <b>_udpsocket</b> class.
			</p>
<hr /><a name="newmethods"></a><br />
<h2>Implementing the cpython 2.3 blocking/timeout model</h2>
<p>
            The following list of cpython socket methods (as of cpython 2.3) are currently not available on jython socket objects, mostly because they are to do with non-blocking I/O or timeouts.
            </p>
<table border="1">
<tr>
<th>Method</th>
<th>Description</th>
<th>Notes</th>
</tr>
<tr class="tabodd">
<td>setblocking</td>
<td>This method permits the programmer to configure a socket to be in blocking or non-blocking mode.</td>
<td>This is the direct equivalent of the java <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#configureBlocking(boolean)">java.nio.channels.SelectableChannel.configureBlocking()</a> method.</td>
</tr>
<tr class="tabeven">
<td>settimeout</td>
<td>This method permits the programmer to set the timeout value for a timeout mode socket.</td>
<td>This is the direct equivalent of the java <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#configureBlocking(boolean)">java.nio.channels.SelectableChannel.configureBlocking()</a> method.</td>
</tr>
<tr class="tabodd">
<td>gettimeout</td>
<td>This method permits the programmer to retrieve the timeout value for a timeout mode socket.</td>
<td>This should return the currently configured timeout value.</td>
</tr>
</table>
<p>
                In the cpython socket model, the above top two methods are closely related. The <a href="http://www.python.org/doc/current/lib/socket-objects.html">cpython module reference for the socket module</a> says the following
            </p>
<p width="80%">
<cite><br />
Some notes on socket blocking and timeouts: A socket object can be in one of three modes: blocking, non-blocking, or timeout. Sockets are always created in blocking mode. In blocking mode, operations block until complete. In non-blocking mode, operations fail (with an error that is unfortunately system-dependent) if they cannot be completed immediately. In timeout mode, operations fail if they cannot be completed within the timeout specified for the socket. The setblocking() method is simply a shorthand for certain settimeout() calls.<br />
            </cite>
</p>
<p width="80%">
<cite><br />
Timeout mode internally sets the socket in non-blocking mode. The blocking and timeout modes are shared between file descriptors and socket objects that refer to the same network endpoint. A consequence of this is that file objects returned by the makefile() method should only be used when the socket is in blocking mode; in timeout or non-blocking mode file operations that cannot be completed immediately will fail.<br />
            </cite>
</p>
<p>
                The following algorithms for a jython implementation of the above methods could be proposed, in order to reflect the same semantics as the cpython API.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> settimeout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            millis = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>timeout <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> millis == <span style="color: #ff4500;">0</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span>millis<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setblocking<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, flag<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">getchannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">configureBlocking</span><span style="color: black;">&#40;</span>flag<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel cannot be configured for blocking'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                However these naive implementations cannot be used in practice, because of the <a href="#deferred">deferred creation of socket implementation objects</a>. This deferred creation of socket implementation objects means that the actual underlying implementation socket may not exist when the settimeout() and setblocking() methods are called. Therefore the socket configuration information must be stored locally on the jython socket object, for use in configuring the socket after it&#8217;s deferred creation.
            </p>
<p>
                Since the goal of this project is cpython 2.3 compatibility, it is proposed that the three explicit modes mentioned in the cpython documenation be adopted as allowable states of jython socket objects. These modes are <b>blocking</b>, <b>non-blocking</b>, <b>timeout</b>, and could be represented as constants as follows.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">MODE_BLOCKING    = <span style="color: #483d8b;">'block'</span>
MODE_NONBLOCKING = <span style="color: #483d8b;">'nonblock'</span>
MODE_TIMEOUT     = <span style="color: #483d8b;">'timeout'</span></pre></div></div>

<p>
                Also, there should be a permitted set of states for any given socket. Whether or not a socket is in one of the permitted states can be checked by assertions.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">_permittedstates = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span></pre></div></div>

<p>
                Note, however, that compatibility with cpython 2.3 <b>on JVM platforms prior to 1.4</b> is also a goal. On such JVMs there are only two permissible modes of operation: <b>blocking</b> and <b>timeout</b>: non-blocking operation is not supported. Therefore, the code above would have to be written as
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
    _permittedmodes = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    _permittedmodes = <span style="color: black;">&#40;</span>MODE_BLOCKING, MODE_TIMEOUT<span style="color: black;">&#41;</span></pre></div></div>

<p>
                The definition of the above methods then becomes (including required modifications to other functions/methods).
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>family, <span style="color: #008000;">type</span>, flags=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
    <span style="color: black;">&#91;</span>.....<span style="color: black;">&#93;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
    <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
    <span style="color: black;">&#91;</span>.....<span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> _tcpsocket:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _config<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> <span style="color: #ff7700;font-weight:bold;">in</span> _permittedmodes
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>: <span style="color: #ff7700;font-weight:bold;">return</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_BLOCKING:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_NONBLOCKING:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">getchannel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">configureBlocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> == MODE_TIMEOUT:
            <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">setSoTimeout</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">timeout</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> settimeout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_NONBLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_TIMEOUT
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = timeout
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setblocking<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, flag<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> flag:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_BLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">blockmode</span> = MODE_NONBLOCKING
            <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				Note the introduction of the <b>_config()</b> method, which will be required on the <b>_tcpsocket</b> and <b>_udpsocket</b> classes. When and where this method should be used is discussed below.
			</p>
<hr /><a name="deferred"></a><br />
<h2>Deferred creation of socket implementation objects</h2>
<p>
                In cpython, after a socket object has been created, it can be used as either a server or a client socket. However, on the java platform, this &#8220;late-binding&#8221; on the socket implementation object itself cannot be used, because server and client socket objects are implemented through separate classes on the JVM.
            </p>
<p>
                The current jython socket module <b>defers</b> the creation of socket objects until it is known for what purpose the socket will be used. For example, when the <b>connect()</b> method is called on a socket object, it is then known that this is to be a client socket.
            </p>
<p>
            	All such methods that determine the final server/client/datagram nature of a socket (i.e. that both create and configure sockets), must be modified to take the new timout and blocking configuration options into account. This can be done through the <b>_config()</b> method discussed in the previous section. The sequence of operations should then be
            </p>
<ol>
<li>Create the socket</li>
<li>Configure the socket for timeouts, blocking, etc</li>
<li>Carry out the desired operation on the socket (e.g. accept, connect, etc)</li>
</ol>
<p>
                Taking the above definition of the <b>socket.connect()</b> method, and modifying it to support blocking configuration gives the following code.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr, port=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;This signifies a client socket&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> port <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            addr = <span style="color: black;">&#40;</span>addr, port<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>
        host, port = addr
        <span style="color: #ff7700;font-weight:bold;">if</span> host == <span style="color: #483d8b;">&quot;&quot;</span>:
            host = java.<span style="color: black;">net</span>.<span style="color: black;">InetAddress</span>.<span style="color: black;">getLocalHost</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        sock = _createclientsock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._setup<span style="color: black;">&#40;</span>sock<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._config<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Configure timeouts, etc, now that the socket exists</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">sock</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>java.<span style="color: black;">net</span>.<span style="color: black;">InetSocketAddress</span><span style="color: black;">&#40;</span>host, port<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
                The following is a typical expected call sequence for using sockets with timeouts.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INT, SOCK_STREAM<span style="color: black;">&#41;</span>
s.<span style="color: black;">settimeout</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'www.python.org'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span></pre></div></div>

<p>
                Socket methods that would require similar modification to the <b>connect()</b> method above are
            </p>
<ol>
<li>_tcpsocket.accept()</li>
<li>_tcpsocket.listen()</li>
<li>_udpsocket.bind()</li>
<li>_udpsocket.connect()</li>
<li>_udpsocket.sendto()</li>
</ol>
<hr /><a name="exception"></a><br />
<h2>Exception compatibility with cpython.</h2>
<p>
				It is desirable that the proposed new jython socket module present the same &#8220;exceptions interface&#8221; as the cpython 2.3 socket module. This is currently not the case with the existing jython socket module. Consider the following two logs of interactive sessions with socket, one on cpython 2.3 and the other on jython 2.1.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Python <span style="color: #ff4500;">2.3</span> <span style="color: black;">&#40;</span><span style="color: #808080; font-style: italic;">#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32</span>
Type <span style="color: #483d8b;">&quot;help&quot;</span>, <span style="color: #483d8b;">&quot;copyright&quot;</span>, <span style="color: #483d8b;">&quot;credits&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;license&quot;</span> <span style="color: #ff7700;font-weight:bold;">for</span> more information.
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'anamethatdoesnotexist'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">?</span>
  File <span style="color: #483d8b;">&quot;&lt;string&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> connect
<span style="color: #dc143c;">socket</span>.<span style="color: black;">gaierror</span>: <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #483d8b;">'getaddrinfo failed'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>
				And
			</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Jython <span style="color: #ff4500;">2.1</span> on java1.4.2 <span style="color: black;">&#40;</span>JIT: null<span style="color: black;">&#41;</span>
Type <span style="color: #483d8b;">&quot;copyright&quot;</span>, <span style="color: #483d8b;">&quot;credits&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;license&quot;</span> <span style="color: #ff7700;font-weight:bold;">for</span> more information.
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'anamethatdoesnotexist'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>innermost last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;console&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">?</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\j</span>ython21<span style="color: #000099; font-weight: bold;">\L</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ocket.py&quot;</span>, line <span style="color: #ff4500;">135</span>, <span style="color: #ff7700;font-weight:bold;">in</span> connect
java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: anamethatdoesnotexist
        at java.<span style="color: black;">net</span>.<span style="color: black;">PlainSocketImpl</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>PlainSocketImpl.<span style="color: black;">java</span>:<span style="color: #ff4500;">153</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#91;</span>.......<span style="color: black;">&#93;</span>
        at org.<span style="color: black;">python</span>.<span style="color: black;">util</span>.<span style="color: black;">jython</span>.<span style="color: black;">main</span><span style="color: black;">&#40;</span>jython.<span style="color: black;">java</span><span style="color: black;">&#41;</span>
&nbsp;
java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: java.<span style="color: black;">net</span>.<span style="color: black;">UnknownHostException</span>: anamethatdoesnotexist</pre></div></div>

<p>
                This difference between exceptions reported on the different platforms makes it more difficult to write robust portable code, and can lead to unnecessary increased code density. It is desirable that the jython socket module generate the same exceptions as the cpython 2.3 module, to make the programmers job more straightforward.
            </p>
<p>
				However, this is non-trivial task. There is a very wide variety of socket exceptions that can be reported, reflecting the wide varieties of errors or problems that can be encountered with sockets, especially in relation to resource usage and other physical considerations. Also, sometimes the same exception differs in meaning subtly between platforms.
            </p>
<p>
				Another point is that although it may not be trivial to report the same exceptions as cpython, the following question should be asked: Is it correct to raise Java platform exceptions from socket methods?
            </p>
<p>
				To be discussed. I know this is not a trivial problem.
            </p>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-socket-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the select module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:05:27 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=115</guid>
		<description><![CDATA[Over the Christmas holidays in 2003, I wrote a design for how Asynchronous Socket I/O might be implemented in jython, using java.nio. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O for jython sockets, which is now a part of the jython distribution.</p>
<p>Although these notes are now out-of-date, having been surpassed by the actual implementation itself, I am publishing them here for historical purposes. The notes are broken down into four main areas.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-115"></span><br />
<hr /><a name="intro"></a><br />
<h2>Implementing the select function and poll objects</h2>
<p>
                The purpose of this document is to discuss implementation strategies for a jython implementation of the <a href="http://www.python.org/doc/current/lib/module-select.html">cpython select module</a>. In cpython, the select module provides two different methods for simultaneously examining the readiness status of a <b>set</b> of I/O channels.
            </p>
<ol>
<li>The <a href="http://www.python.org/doc/current/lib/module-select.html">select</a> function, which is derived from the <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?select+2">original Unix select call</a>, and takes as parameters three lists of file descriptors:
<ol>
<li>a list containing file descriptors which may be <b>readable</b>
</li>
<li>a list containing file descriptors which may be <b>writable</b>
</li>
<li>a list containing file descriptors which may have <b>out-of-band</b>(OOB) data</li>
</ol>
<p>                When the select function is called, it reads through each of these lists, and prepares its own internal lists of file descriptors which are to be &#8220;selected&#8221;. It then examines the readiness of the file descriptors in this internal list, and returns three lists which are subsets of the three lists passed in as parameters.</li>
<li>
<a href="http://www.python.org/doc/current/lib/poll-objects.html">Poll objects</a>, which are object-oriented descendants of the select function. In order to examine the readiness status of multiple file descriptors, the programmer creates a poll object. File descriptors are explicitly registered with the poll object. These descriptors are checked every time the poll objects <b>poll()</b> method is called, until the file descriptor is explicitly <b>unregistered</b>.</li>
</ol>
<p>
                As mentioned on the cpython <a href="http://www.python.org/doc/current/lib/poll-objects.html">Poll objects documentation page</a>, poll objects are superior to the select function call, since they <i>only require listing the file descriptors of interest, while select() builds a bitmap, turns on bits for the fds of interest, and then afterward the whole bitmap has to be linearly scanned again</i>. This means that performance of poll objects should be better than the select function.
            </p>
<p>
                Although poll objects may be superior, the select function call is still supported in cpython, for the following reasons.
            </p>
<ol>
<li>
<b>Historic</b>. There is a substantial body of code written in cpython which uses the select function.</li>
<li>
<b>Windows</b>. Windows does not support poll objects (Windows has it&#8217;s own equivalent API call).</li>
<li>
<b>Unix</b>. Although most modern unices support poll objects, there are still some variants that do not.</li>
</ol>
<p>
                As discussed below, cpython poll objects exhibit a very similar model to <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html">java.nio.channels.Selector</a> objects, and thus it is natural to implement one using the other. Once poll objects have been implemented, a jython implementation of the select function can be layered on top of them.
            </p>
<hr /><a name="selector"></a><br />
<h2>Implementing poll objects with java Selector objects</h2>
<p>
                A likely approach to implementing cpython poll objects in jython is to implement them using java Selector objects.
            </p>
<p>
                The following are similarities between cpython <a href="http://www.python.org/doc/current/lib/poll-objects.html">select.poll</a> objects and <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html">java.nio.channels.Selector</a> objects.
            </p>
<ol>
<li>Both are single objects which can &#8220;watch&#8221; multiple I/O channels at once.</li>
<li>Both monitor a set of I/O channels which have been explicitly <b>registered</b> with the object.</li>
<li>Both return a set of &#8220;keys&#8221; which indicate which channels are ready for I/O. In case of cpython, this is in the form of a list of tuples giving <b>(file descriptor, event mask)</b>. In java&#8217;s case, this is in the form of a set of <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html">java.nio.channels.SelectionKey</a>s, which contain an event mask (or in java terminology, a set of <b>interestOps()</b>).</li>
<li>Both objects support the concept of a timeout, i.e. that the method call which watches the set of registered channels can timeout after a user specified time.</li>
<li>Both objects support the concept of taking a &#8220;snapshot view&#8221;, i.e. a zero-length timeout.</li>
<li>Both objects support the concept of waiting indefinitely for some readiness notification to appear.</li>
</ol>
<p>
                The important differences are as follows
            </p>
<ol>
<li>Java Selector objects have clearly defined semantics when a single selector object is operated from <b>multiple threads</b>. In contrast, the documentation for cpython poll objects makes no guarantees (or even statements) at all about access to poll objects from multiple threads (presumably this is related to the fact that cpython has a Global Interpreter Lock (GIL) which prevents more than one thread from executing python at any given time. See below under <a href="#threading">Threading</a> for more information).</li>
<li>Java SelectionKey objects permit the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#attach(java.lang.Object)">attachment of application objects</a>, meaning that the programmer can attach a handler object to each channel, and which might be rsponsible for handling all I/O on the channel. Note however that although this facility is useful when writing application frameworks, it is unlikely to be useful in the case of implementing a cpython compatible select module, since cpython poll objects do not support the &#8220;attachment&#8221; of application objects to I/O channels to be watched. However, the <a href="/asynchronous-networking-for-jython-the-asyncore-module/">asyncore module</a> may be an ideal place to exploit this feature.</li>
</ol>
<hr /><a name="threading"></a><br />
<h2>Threading and the cpython Global Interpreter Lock</h2>
<p>
            	TBD: Need to understand possible use-cases for calling poll objects from multiple threads.
            </p>
<p>
            	If you have come across a need to call poll objects from multiple threads, I&#8217;d like to hear about it.
            </p>
<hr /><a name="register"></a><br />
<h2>Registering and unregistering channels</h2>
<p>
                The cpython documentation states that when a channel is to be registered, the parameter passed can be either of two object types:-
            </p>
<ol>
<li>The channels file descriptor</li>
<li>An object which has a <b>fileno()</b> method which returns a file descriptor.</li>
</ol>
<p>
                In the jython implementation of poll objects, a SelectableChannel object is required. Therefore, it is proposed that in jython the same model as cpython be adopted, with the term <b>file descriptor</b> replaced by the term <b>SelectableChannel</b>.
            </p>
<p>
                If an object is registered which is an instance of <b>java.nio.channels.SelectableChannel</b> or any of subclasses, then that object represents the channel which is to be watched.
            </p>
<p>
                If the object is <b>not</b> such an instance, then the objects <b>fileno()</b> method should be called, to attempt retrieve a SelectableChannel. If the method does not exist, then the object is not watchable, and an exception should be raised. If the method returns an object, but that object is not a SelectableChannel, the channel is unwatchable and an exception should be raised. If the method returns an object and that object is a SelectableChannel, then that object is the channel to be watched.
            </p>
<p>
                Suggested code for this purpose is
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, channel<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>channel, java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectableChannel</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> channel
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
                result = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>channel, <span style="color: #483d8b;">'fileno'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>result, java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectableChannel</span><span style="color: black;">&#41;</span>:
                    <span style="color: #ff7700;font-weight:bold;">return</span> result
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel '</span><span style="color: #66cc66;">%</span>s<span style="color: #483d8b;">' is not a watchable channel'</span> <span style="color: #66cc66;">%</span> channel<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> JynioException<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Channel '</span><span style="color: #66cc66;">%</span>s<span style="color: #483d8b;">' is not a watchable channel'</span> <span style="color: #66cc66;">%</span> channel<span style="color: black;">&#41;</span></pre></div></div>

<p>
                A typical call sequence using the register function is given here. Note that this code should work in both cpython and jython.
            </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;">select</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
pobj = <span style="color: #dc143c;">select</span>.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
s = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
s.<span style="color: black;">setblocking</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'www.python.org'</span>, <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>s, <span style="color: #dc143c;">select</span>.<span style="color: black;">POLLIN</span> | <span style="color: #dc143c;">select</span>.<span style="color: black;">POLLOUT</span><span style="color: black;">&#41;</span>
readychans = pobj.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<hr /><a name="datastructs"></a><br />
<h2>Internal data of the poll object</h2>
<p>
                The poll object needs to keep track of the channels which it is watching. In java, java.nio.channels.Selector objects are used to watch multiple channels. Therefore, it is proposed to have a Selector as an instance variable of every poll object, against which all channels can be registered. The Selector should be created at __init__ time of the poll object, like so.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span></pre></div></div>

<p>
                In the cpython model, a channel <b>is registered</b> with a watcher, whereas in java the channel <b>registers itself</b> with the watcher, returning a SelectionKey representing the registration. This means that when a Selector returns a set of channels that are ready for I/O operations, it will return a set of SelectionKeys. But we need to return the original object back to the programmer that they passed in. So we need a mechanism for mapping SelectionKeys back to original parameters.
            </p>
<p>
                When a SelectionKey is returned from a Selector, the channel corresponding to that key can be obtained through the <b>channel()</b> method. Further, since we know that that channel represents a socket, we can retrieve the users original socket through the <b>socket()</b> method. However, if we do not keep track of the users original object, then we cannot know from the SelectionKey which object the user passed in. Therefore, we need to keep track of the original object the user passed into the function. This could be done with a simple dictionary which is internal to the jython poll object. The key for the dictionary would be the SelectableChannel corresponding to the channel.
            </p>
<p>
                When a channel is <b>unregistered</b> with a poll object, the channel should no longer be watched. The java model, however, is slightly different than what might be expected (surprise!): instead of a watcher unregistering a watchable channel, the key representing the registration of a watchable channel with a watcher must be cancelled! Therefore, it will be necessary to keep track of all SelectionKeys generated by the Selectable/Selector/registration process, so that they can be cancelled later.
            </p>
<p>
                It is proposed to store this information in a simple python dictionary which is internal to the jython poll object. The key for the dictionary would be the SelectableChannel corresponding to the channel. The values in the dictionary should contain the following.
            </p>
<ol>
<li>
<b>userobject</b>, i.e. the object which the user passed into the registration function, and which should be returned to them when the channel is ready for I/O.</li>
<li>
<b>SelectionKey</b>, i.e. the SelectionKey representing the registration with the internal Selector object. This is so that the registration can be cancelled at a later stage.</li>
</ol>
<p>
                This dictionary should created at __init__ time of the poll object, and modified at every channel registration and unregistration. The following are suggested algorithms for the poll object. Note that, according to the cpython 2.3 documentation, it is <b>not</b> an error for a channel to be registered twice with a poll object, but any attempt to unregister a channel that was never registered should result in a KeyError. Note that this code ignores the need for event flags, the implementation of which will be discussed below.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
     <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
         <span style="color: #808080; font-style: italic;"># Implementation which seeks a SelectableChannel object given above</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject, flags<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Flags ignored for now</span>
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        selectionkey = channel.<span style="color: black;">register</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">selector</span>, flags<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span> = <span style="color: black;">&#40;</span>userobject, selectionkey<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> unregister<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">cancel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span></pre></div></div>

<hr /><a name="flags"></a><br />
<h2>Mapping cpython event flags to java interest ops</h2>
<p>
                When a channel is registered with a watcher, the programmer defines a set of events in which they are interested. In cpython, this is done through OR&#8217;ing bitmasks containing the following possible values
            </p>
<table border="1">
<tr>
<th>Flag</th>
<th>Meaning</th>
</tr>
<tr class="tabodd">
<td>POLLIN</td>
<td>Check whether the channel has data ready for reading</td>
</tr>
<tr class="tabeven">
<td>POLLOUT</td>
<td>Check whether the channel is ready for writing data</td>
</tr>
<tr class="tabodd">
<td>POLLPRI</td>
<td>Check whether there is <b>Out-Of-Band</b> data present on this channel.</td>
</tr>
</table>
<p>
                The following are important to note
            </p>
<ol>
<li>Cpython does not have an event flag to represent a <b>CONNECT</b> event. Instead, a client socket is known to be connected when it is ready for writing, i.e. a <b>POLLOUT</b> event is generated.</li>
<li>Cpython does not have an event flag to represent a <b>ACCEPT</b> event, i.e. that a server socket accept() would not block if called, and would return a new socket. Instead, a server socket is known to be ready to accept when it is ready for reading, i.e. a <b>POLLIN</b> event is generated.</li>
<li>Note the above seems only to be documented in the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">cpython documentation for the asyncore module</a>. It is also interesting to note that the asyncore module has reverse-engineered its own <b>pseudo-events</b> to represent the <b>CONNECT</b> and <b>ACCEPT</b> events.</li>
</ol>
<p>
                Java also uses a OR&#8217;ed bitmasks of flags to represent the sert of events that is of interest on the channel. Java defines the following constants in the java.nio.channels.SelectionKey object.
            </p>
<table border="1">
<tr>
<th>Flag</th>
<th>Meaning</th>
</tr>
<tr class="tabodd">
<td>OP_ACCEPT</td>
<td>Check whether the server socket channel is ready for accepting. Server socket channels support this event only! They do not support OP_READ!</td>
</tr>
<tr class="tabeven">
<td>OP_CONNECT</td>
<td>Check whether the client socket channel is connected</td>
</tr>
<tr class="tabodd">
<td>OP_READ</td>
<td>Check whether the channel has data ready for reading</td>
</tr>
<tr class="tabeven">
<td>OP_WRITE</td>
<td>Check whether the channel is ready for writing data</td>
</tr>
</table>
<p>
                Obviously, this presents some difficulties, since there are discrepancies between the event flags that are used by cpython and java. Cpython uses the POLLIN flag to represent two events that are represented by separate flags in java: OP_ACCEPT and OP_READ. Similarly, cpython uses the POLLOUT flag to represent both the java events OP_CONNECT and OP_WRITE. There is no way in cpython to specify the <b>CONNECT</b> or <b>ACCEPT</b> events, but these are required by Java. Conundrum!
            </p>
<p>
                A naive solution to this problem might be to attempt to set both java flags as being of interest when the relevant cpython flag is specified. For example, use both event mask <b>OP_READ | OP_ACCEPT</b> when the python mask <b>POLLIN</b> is specified. However, this may result in error, since OP_ACCEPT is only a valid flag on server socket channels: it would probably generate an IllegalArgumentException if used on a client socket (see the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#interestOps(int)">documentation for the SelectionKey.interestOps()</a> method for more information. As mentioned on that page, if an event flag is not present in the mask of <b>valid operations</b> on that channel (as determined by the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectableChannel.html#validOps()">SelectableChannel.validOps()</a> method, then an exception is raised.
            </p>
<p>
                Therefore, a proposed solution is to only add these <b>implied</b> java events when they are present in the validOps mask for the channel being registered. Code to carry out this proposed mapping is as follows
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectionKey</span> <span style="color: #ff7700;font-weight:bold;">import</span> OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ
&nbsp;
POLLIN   = <span style="color: #ff4500;">1</span>
POLLOUT  = <span style="color: #ff4500;">2</span>
POLLPRI  = <span style="color: #ff4500;">4</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, channel, mask<span style="color: black;">&#41;</span>:
        jmask = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
            <span style="color: #808080; font-style: italic;"># Note that OP_READ is NOT a valid event on server socket channels.</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT:
                jmask = OP_ACCEPT
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                jmask = OP_READ
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
            jmask |= OP_WRITE
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT:
                jmask |= OP_CONNECT
        <span style="color: black;">&#91;</span>....<span style="color: black;">&#93;</span></pre></div></div>

<p>
            Note that the absence of the python POLLPRI constant is discussed below.
        </p>
<p>
            Combining this code with the code given above, this gives a final definition of the poll object (minus the definition of the poll() method) as follows.
        </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>
<span style="color: #ff7700;font-weight:bold;">from</span> java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">SelectionKey</span> <span style="color: #ff7700;font-weight:bold;">import</span> OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ
&nbsp;
<span style="color: #808080; font-style: italic;"># These values should be checked in the cpython implementation.</span>
&nbsp;
POLLIN   = <span style="color: #ff4500;">1</span>
POLLOUT  = <span style="color: #ff4500;">2</span>
POLLPRI  = <span style="color: #ff4500;">4</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">selector</span> = java.<span style="color: black;">nio</span>.<span style="color: black;">channels</span>.<span style="color: black;">Selector</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
     <span style="color: #ff7700;font-weight:bold;">def</span> _getselectable<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
         <span style="color: #808080; font-style: italic;"># Implementation which seeks a SelectableChannel object given above</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject, mask<span style="color: black;">&#41;</span>:
        jmask = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
            <span style="color: #808080; font-style: italic;"># Note that OP_READ is NOT a valid event on server socket channels.</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT:
                jmask = OP_ACCEPT
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                jmask = OP_READ
        <span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
            jmask |= OP_WRITE
            <span style="color: #ff7700;font-weight:bold;">if</span> channel.<span style="color: black;">validOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT:
                jmask |= OP_CONNECT
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        selectionkey = channel.<span style="color: black;">register</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">selector</span>, jmask<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span> = <span style="color: black;">&#40;</span>userobject, selectionkey<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> unregister<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, userobject<span style="color: black;">&#41;</span>:
        channel = <span style="color: #008000;">self</span>._getselectable<span style="color: black;">&#40;</span>userobject<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">cancel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>channel<span style="color: black;">&#93;</span></pre></div></div>

<hr /><a name="poll"></a><br />
<h2>An implementation of the poll method</h2>
<p>
                We are now in a position to define the <b>poll()</b> method of poll objects. The return value from this function should be a list of tuples, containing (channel, event mask), where <b>event mask</b> has bits set for all events that occurred on the channel. Since the event mask returned from the internal java.nio.channels.Selector object will possibly contain the extended java events OP_ACCEPT and OP_CONNECT, these should be mapped to the python events POLLOUT and POLLIN respectively.
            </p>
<p>
                The cpython <b>poll.poll()</b> method takes a timeout parameter, which means different things depending on its value. Java uses separate methods to represent these different timeout scenarios. The mapping from one to the other is given in this table.
            </p>
<table border="1">
<tr>
<th>Timeout value</th>
<th>Cpython meaning</th>
<th>Java equivalent</th>
</tr>
<tr class="tabodd">
<td>None</td>
<td>The poll call is to block until at least one channel is ready for operation.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select()">Selector.select()</a></td>
</tr>
<tr class="tabeven">
<td>Negative value</td>
<td>Same as timeout value of None</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select()">Selector.select()</a></td>
</tr>
<tr class="tabodd">
<td>Positive value</td>
<td>The value gives the timeout value <b>in millseconds</b>.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#select(long)">Selector.select(long)</a></td>
</tr>
<tr class="tabeven">
<td>Zero</td>
<td>The value gives a timeout value of zero milliseconds.</td>
<td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html#selectNow()">Selector.selectNow()</a></td>
</tr>
</table>
<p>
                Therefore, different methods of the internal Selector object will have to be called, depending on the timeout value specified.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> poll:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> poll<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, timeout=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> timeout <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">or</span> timeout <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> timeout == <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: black;">selectNow</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #808080; font-style: italic;"># No multiplication required: both cpython and java use millisecond timeouts</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span>
        selectedkeys = <span style="color: #008000;">self</span>.<span style="color: black;">selector</span>.<span style="color: black;">selectedKeys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># is this thread-safe?</span>
        results = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> selectedkeys: <span style="color: #808080; font-style: italic;"># Naive implementation, returned list is actually a java.util.Set</span>
            jmask = k.<span style="color: black;">readyOps</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            pymask = <span style="color: #ff4500;">0</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_READ: pymask |= POLLIN
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_WRITE: pymask |= POLLOUT
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_ACCEPT: pymask |= POLLIN
            <span style="color: #ff7700;font-weight:bold;">if</span> jmask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> OP_CONNECT: pymask |= POLLOUT
            <span style="color: #808080; font-style: italic;"># Now return the original userobject, and the return event mask</span>
            <span style="color: #808080; font-style: italic;"># A python 2.2 generator would be sweet here</span>
            results.<span style="color: black;">append</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">chanmap</span><span style="color: black;">&#91;</span>k.<span style="color: black;">channel</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, pymask<span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> results</pre></div></div>

<hr /><a name="outofband"></a><br />
<h2>How to deal with Out-Of-Band data</h2>
<p>
                In cpython, it is possible to check for the presence of <b>Out-Of-Band</b> data on a channel. <a href="http://www.listproc.bucknell.edu/archives/netbook/200104/msg00003.html">Out-of-Band</a> data, also known as <b>priority</b> data or <b>urgent</b> data, is a TCP feature whereby bytes can be sent on a socket which bypass the normal sequencing restrictions imposed on data sent through a socket.
            </p>
<p>
            	However, although this is a built-in feature of TCP sockets, such out-of-band data is rarely used in actual protocol implementations. Nonetheless, there may be software out there which uses this facility. The readiness status for presence of this data is checked by passing the flag <b>POLLPRI</b> when registering the channel.
            </p>
<p>
                Currently, the java.nio non-blocking APIs seem to have minimal support for Out-Of-Band data. <b>There are no events masks with which one can register interest in such priority data</b>. This is confirmed on the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#setOOBInline(boolean)">documentation page for java.net.Socket.setOOBInline() method</a>, which says: &#8220;<i>Note, only limited support is provided for handling incoming urgent data. In particular, no notification of incoming urgent data is provided and there is no capability to distinguish between normal data and urgent data unless provided by a higher level protocol</i>&#8220;.
            </p>
<p>
                Because of this lack of support for priority/urgent data on the java platform, it is proposed that this form of processing <b>not be supported</b> in this module. If the programmer requires the use of urgent data with jython, i.e. on the java platform, then they will probably be sophisticated enough to bypass this implementation of the select module in jython, and go direct to the java API. A consequent question is whether POLLPRI flags should simply be ignored when used, or should raise an UnsupportedOperation exception.
            </p>
<p>
                If this is deemed to be an unacceptable compromise, then I have no solution to propose for the problem.
            </p>
<hr /><a name="select"></a><br />
<h2>Implementing the select function using poll objects.</h2>
<p>
                Now that we have finished the implementation of poll objects, we can use them to implement the select function, also in the cpython select module.
            </p>
<p>
                The only complexity is that the select function takes separate lists for channels that are to be examined for read and write events. It might be required that the user wants to watch a channel for both read and write events, so a given channel might be present in both lists. This means that if a channel is given in both lists, it must only be registered once with the selector object, using an event mask that checks for both READ and WRITE events.
            </p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">select</span> <span style="color: black;">&#40;</span> read_fd_list, write_fd_list, outofband_fd_list<span style="color: black;">&#41;</span>:
	<span style="color: #808080; font-style: italic;"># First create a poll object to do the actual watching.</span>
	pobj = poll<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># Check the read list</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> read_fd_list:
		mask = POLLIN
		<span style="color: #ff7700;font-weight:bold;">if</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> write_fd_list:
			mask |= POLLOUT
		pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd, mask<span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># And now the write list</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> write_fd_list:
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> fd <span style="color: #ff7700;font-weight:bold;">in</span> read_fd_list: <span style="color: #808080; font-style: italic;"># fds in both have already been registered.</span>
			pobj.<span style="color: black;">register</span><span style="color: black;">&#40;</span>fd, POLLOUT<span style="color: black;">&#41;</span>
	results = poll.<span style="color: black;">poll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #808080; font-style: italic;"># Now start preparing the results</span>
	read_ready_list, write_ready_list, oob_ready_list = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> fd, mask <span style="color: #ff7700;font-weight:bold;">in</span> results:
		<span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLIN:
			read_ready_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> mask <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;</span> POLLOUT:
			write_ready_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>fd<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> read_ready_list, write_ready_list, oob_ready_list</pre></div></div>

<hr /><a name="untested"></a><br />
<h2>Complete but untested code based on these notes.</h2>
<p>
				The following code <b>should</b> be a complete implementation of the cpython select module, in jython, using java APIs. However, the following are important points
            </p>
<ol>
<li>
<b>Will not work without socket mods</b>. In order for this code to work, a number of modifications would have to be made to the <a href="/asynchronous-networking-for-jython-the-socket-module/">jython socket module</a>. I currently have no plans to make these modifications: I can&#8217;t afford the time. Maybe in a few months.</li>
<li>
<b>Code is completely untested</b>. This code has only been tested for correct syntax. It has <b>never</b> even been run.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-select-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous networking for jython: the asyncore module</title>
		<link>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/</link>
		<comments>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/#comments</comments>
		<pubDate>Fri, 26 Dec 2003 21:00:28 +0000</pubDate>
		<dc:creator>alan.kennedy</dc:creator>
				<category><![CDATA[jython]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://jython.xhaus.com/?p=117</guid>
		<description><![CDATA[Over the Christmas holidays in 2003, I wrote a design for how Asynchronous Socket I/O might be implemented in jython, using java.nio. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O [...]]]></description>
			<content:encoded><![CDATA[<p>Over the Christmas holidays in 2003, I wrote a design for how <a href="http://en.wikipedia.org/wiki/Asynchronous_I/O">Asynchronous Socket I/O</a> might be implemented in jython, using <a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/">java.nio</a>. I wrote up some notes in HTML, and placed them on a group of pages on xhaus.com. These notes were the basis of the design which I later used to implement asynchronous I/O for jython sockets, which is now a part of the jython distribution.</p>
<p>Although these notes are now out-of-date, having been surpassed by the actual implementation itself, I am publishing them here for historical purposes. The notes are broken down into four main areas.</p>
<ol>
<li>
<a href="/asynchronous-networking-for-jython-overview/">Overview</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-socket-module/">Socket module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-select-module/">Select module</a>
</li>
<li>
<a href="/asynchronous-networking-for-jython-the-asyncore-module/">Asyncore module</a>
</li>
</ol>
<p>For documentation on how to use the jython&#8217;s asynchronous socket I/O, see the documentation for the <a href="http://wiki.python.org/jython/NewSocketModule">socket</a>, <a href="http://wiki.python.org/jython/SelectModule">select</a>, <a href="http://www.python.org/doc/2.5/lib/module-asyncore.html">asyncore</a>, and <a href="http://www.python.org/doc/2.5/lib/module-asynchat.html">asynchat</a> modules.</p>
<p><span id="more-117"></span><br />
<hr /><a name="intro"></a><br />
<h2>Introduction</h2>
<p>
				The purpose of this document is to discuss the implementation of the <a href="http://www.python.org/doc/current/lib/module-asyncore.html">cpython asycnore module</a> in jython.
			</p>
<p>
				The purpose of the asyncore module is to add the last piece of the puzzle in asynchronous processing: <b>the dispatcher</b>. A dispatcher is responsible for watching multiple registered channels. When a readiness event occurs on any channel, the dispatcher calls special events of a handler object associated with each channel.
			</p>
<p>
				Important points to note about the existing cpython asyncore module are as follows.
			</p>
<ol>
<li>It is written pure python.</li>
<li>It uses only the interface defined by the cpython select module.</li>
<li>It recreates both the <b>ACCEPT</b> and <b>CONNECT</b> events, even though the cpython select module &#8220;hides&#8221; these events as <b>POLLIN</b> and <b>POLLOUT</b> events.</li>
</ol>
<p>
				There are three main strategies that can be adopted for implementing the asyncore module, along with pros and cons. These are listed in the sections below.
			</p>
<hr /><a name="existing"></a><br />
<h2>Use the existing cpython asyncore module</h2>
<p>
				The simplest and quickest option for providing asyncore support in jython is to use the existing cpython module.  The advantages of this approach include
			</p>
<ol>
<li>No new code need be written</li>
<li>Existing code is widely used, and thus well tested.</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>Potential for error because of the possibility of different semantics of <b>ACCEPT</b> and <b>CONNECT</b> events on cpython vs. java (on multiple platforms).</li>
<li>Mildly inefficient, because of all the mask translation and dictionary lookups</li>
<li>Existing code is messy because of varying platform support for the <b>select.select()</b> and <b>select.poll()</b> objects in cpython.</li>
</ol>
<hr /><a name="jythonrewrite"></a><br />
<h2>Write a jython specific module, using jython</h2>
<p>
				Another approach is write a jython specific asyncore module, written in jython, but directly using the java.nio APIs. There is quite a close correlation between the models in the cpython asyncore module and java.nio.channels.Selector objects. It is possible to write a more efficient asyncore implemenation by using the java APIs directly. The advantanges of this approach are
			</p>
<ol>
<li>Can be more robust because of java&#8217;s explicit support for <b>ACCEPT</b> and <b>CONNECT</b> events, which can be directly translated to the relevant &#8220;dispatcher&#8221; events.</li>
<li>Can be slightly more efficient, because it avoids a layer of calls to jython implemented <a href="/asynchronous-networking-for-jython-the-select-module/">poll objects</a>.</li>
<li>Asyncore model maps directly onto semantics of a java.nio.channels.Selector (even more than cpython)</li>
<li>&#8220;Dispatcher&#8221; objects can be registered as <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html#attach(java.lang.Object)">attached objects</a> to the java.nio.channels.SelectionKeys that represent them. This would make them directly available to the <b>asyncore.loop()</b> function (which would receive a set of java.nio.channels.SelectionKeys, each having the dispatcher as an attachment, which avoids the dictionary lookups involved in poll objects.</li>
<li>Can easily be translated to java later on.</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>New code needs to be written. Not too much though.</li>
<li>Extensive testing will have to be done to ensure that the new module implements the precise contract of the cpython asyncore module.</li>
</ol>
<p>
				TBD: Must write sample code for a jython asyncore module.
			</p>
<hr /><a name="rewritejava"></a><br />
<h2>Write jython specific module, using java</h2>
<p>
				The last major approach is to, as above, write a jython specific module, but in java. However, this is unlikely to the optimal approach, at least in the short term. Advantages include
			</p>
<ol>
<li>Best possible efficiency</li>
</ol>
<p>The disadvantages are</p>
<ol>
<li>A lot of hard work!</li>
<li>The java/jython object model is likely to change soon.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jython.xhaus.com/asynchronous-networking-for-jython-the-asyncore-module/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>
