<?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>Operations and other mysteries</title>
	<atom:link href="http://blogs.operationaldynamics.com/andrew/feed" rel="self" type="application/rss+xml" />
	<link>http://blogs.operationaldynamics.com/andrew</link>
	<description>Comments and notes by Andew Cowie</description>
	<lastBuildDate>Sat, 25 May 2013 13:40:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>We all wish we knew what we were doing on Google Plus</title>
		<link>http://blogs.operationaldynamics.com/andrew/personal/we-all-wish-we-knew-what-we-were-doing-on-google-plus</link>
		<comments>http://blogs.operationaldynamics.com/andrew/personal/we-all-wish-we-knew-what-we-were-doing-on-google-plus#comments</comments>
		<pubDate>Sat, 25 May 2013 13:40:33 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=963</guid>
		<description><![CDATA[Public Service Announcement I have a number of colleagues who are die-hard Facebook users but due to relentless assimilation by the evangelizing hegemonistic swarm that is the Big G, they have been forced to try Google+ for the first time. I&#8217;ve noticed them all struggling with similar incongruencies. Posts are not chat channels The biggest [...]]]></description>
				<content:encoded><![CDATA[<p><em>Public Service Announcement</em></p>

<p>I have a number of colleagues who are die-hard Facebook users but due to relentless assimilation by the evangelizing hegemonistic swarm that is the Big G, they have been forced to try Google+ for the first time. I&#8217;ve noticed them all struggling with similar incongruencies.</p>

<h2>Posts are not chat channels</h2>

<p>The biggest difference is controlling distribution; for instance, the following scenario is common:</p>

<blockquote>
  <p>George Jones shared a photo of their &#8220;business&#8221; trip with all his friends!</p>
  
  <p>Andrew Cowie writes a comment praising the beach and sunset in said photo.</p>
  
  <p>George Jones replies <em>&#8220;Hey, yeah, it&#8217;s great. So I heard you were in Europe last week?&#8221;</em></p>
</blockquote>

<p>What George doesn&#8217;t seem to realize is that he just asked that question not of me but of the thirty people he shared the original post with. Which is probably not what he had in mind. I&#8217;ve run into this with my parents a fair bit; Dad keeps commenting personally on my public posts. Not sure he quite realizes several thousand people will see his remark :)</p>

<h2>Circles aren&#8217;t as useful as they seem</h2>

<p>Which brings me to posting publicly vs sharing with a given circle or circles. Most of the people I know gave up on circles and just  publishing most things they write as &#8220;public&#8221; &#8212; which makes Google+ posts a long-hand version of Twitter. I certainly am followed by tons of people who aren&#8217;t in my circles, so they only see my posts if I hit &#8220;public&#8221;, which is annoying: because I don&#8217;t really want to bombard my family with my professional and technology posts. But there&#8217;s no &#8220;public except this circle&#8221; visibility setting, so if I want a wider audience for my general posts, I&#8217;m sorta stuck with it. This leads to a much lower signal-to-noise ratio for my friends (the people I care about the most!) for the dubious benefit of writing to people I don&#8217;t know, and also leads to the aforementioned friends and family thinking they have to make personal commenting on such posts.</p>

<h2>Posts are not really a communication channel</h2>

<p>Using Hangouts for casual 1:1 chat is <em>much</em> easier than trying to conduct chat in the comments of a formal post. Someone commenting on a post <em>does</em> raise it to the top of your stream, but when that happens it&#8217;s not obvious that a comment on that post is actually the continuation of a personal discussion; all you see is &#8220;The post about the Muppets has a new comment!&#8221;. Yeah, I bet.</p>

<p>Meanwhile, after years of being a disaster zone, Google has finally merged GTalk, Google Video, the former Google Hangouts, the in-browser Chat sidebar, Gmail chat, the Android G+ app messenger, and lord knows what else under the banner &#8220;Hangouts&#8221;. So it&#8217;s unified now, which is a big advance, and at last you can rather seamlessly and in a device independent way switch between chat and video. This is very awesome.</p>

<h2>Name prefixing considered useful</h2>

<p>If you <em>are</em> going to reply to someone in a comment stream on a (public or otherwise) post, you might consider prefacing the comment with the person&#8217;s G+ username; that way a) they&#8217;ll [likely] get a notification and b) it&#8217;s obvious you&#8217;re speaking to that person and not to everyone.</p>

<blockquote>
  <p>&#8220;Hey <a style="text-decoration: none;" href="https://plus.google.com/104216419012637157644"><span style="color: blue;">+Andrew Cowie</span></a>, I&#8217;m glad you like the picture. Heard you passed through Europe last week. Pity we didn&#8217;t quite connect. Catch you next trip!&#8221;</p>
</blockquote>

<p>Or so.</p>

<h2>Build it and they will [be forced to] come</h2>

<p>Google Plus has been a hodge-podge since the beginning, but it&#8217;s also evident that they&#8217;re working really hard to improve the integration between services (interesting read about &#8220;<a href="http://www.theverge.com/2013/5/15/4318830/inside-hangouts-googles-big-fix-for-its-messaging-mess">cleaning up the mess</a>&#8221; over at the Verge about this). I don&#8217;t want to seem that enthusiastic about it, because frankly it&#8217;s absurd that they didn&#8217;t have this wired tight before they launched in the first place. For me the fact that Hangouts are now an integrated messaging system is a watershed; I can only hope this model of cross functional team collaboration helps Google improve other areas of their services so desperately in need of some QA.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/personal/we-all-wish-we-knew-what-we-were-doing-on-google-plus/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>http-streams 0.5.0 released</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-5-0-released</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-5-0-released#comments</comments>
		<pubDate>Tue, 23 Apr 2013 13:03:19 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=957</guid>
		<description><![CDATA[I&#8217;ve done some internal work on my http-streams package. Quite a number of bug fixes, which I&#8217;m pleased about, but two significant qualitative improvements as well. First we have rewritten the &#8220;chunked&#8221; transfer encoding logic. The existing code would accept chunks from the server, and feed them as received up to the user. The problem [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve done some internal work on my <a class="package" href="http://hackage.haskell.org/package/http-streams">http-streams</a> package. Quite a number of bug fixes, which I&#8217;m pleased about, but two significant qualitative improvements as well.</p>

<p>First we have rewritten the &#8220;chunked&#8221; transfer encoding logic. The existing code would accept chunks from the server, and feed them as received up to the user. The problem with this is the <em>server</em> is the one deciding the chunk size, and that means you can end up being handed multi-megabyte ByteStrings. Not exactly streaming I/O. So I&#8217;ve hacked that logic so that it <code>yield</code>&#8216;s bites of maximum 32 kB until it has iterated through the supplied chunk, then moves on to the next. Slight increase in code complexity internally, but much smoother streaming behaviour for people using the library.</p>

<p>Secondly I&#8217;ve brought in the highly tuned HTTP header parsing code from Gregory Collins&#8217;s new <a class="package" href="http://hackage.haskell.org/package/snap-server">snap-server</a>. Our parser was already pretty fast, but this gave us a 13% performance improvement. Nice.</p>

<p>We changed the types in the <code>openConnection</code> functions; Hostname and Port are ByteString and Word16 now, so there&#8217;s an API version bump to 0.5.0. Literals will continue to work so most people shouldn&#8217;t be affected.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-5-0-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>http-streams 0.4.0 released</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-4-0-release</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-4-0-release#comments</comments>
		<pubDate>Sat, 23 Mar 2013 14:22:54 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=934</guid>
		<description><![CDATA[Quick update to http-streams, making a requested API change to the signature of the buildRequest function as well as pushing out some bug fixes and performance improvements. You no longer need to pass the Connection object when composing a Request, meaning you can prepare it before opening the connection to the target web server. The [...]]]></description>
				<content:encoded><![CDATA[<p>Quick update to <a class="package" href="http://hackage.haskell.org/package/http-streams">http-streams</a>, making a requested API change to the signature of the <code>buildRequest</code> function as well as pushing out some bug fixes and performance improvements.</p>

<p>You no longer need to pass the Connection object when composing a Request, meaning you can prepare it before opening the connection to the target web server. The required HTTP 1.1 <code>Host:</code> header is added when <code>sendRequest</code> is called, when the request is written to the server. If you need to see the value of the <code>Host:</code> field that will be sent (ie when debugging) you can call the <code>getHostname</code> function.</p>

<p>I&#8217;ve added an &#8220;API Change Log&#8221; to the <a href="https://github.com/afcowie/http-streams#readme" class="repository">README</a> file on GitHub, and the blog post <a href="http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-introduction">introducing http-streams</a> has been updated reflect the signature change.</p>

<p>Thanks to Jeffrey Chu for his contributions and to Gregory Collins for his advice on performance improvement; this second release is about 9% faster than the original.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-0-4-0-release/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An HTTP client in Haskell using io-streams</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-introduction</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-introduction#comments</comments>
		<pubDate>Wed, 06 Mar 2013 08:27:06 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=860</guid>
		<description><![CDATA[An HTTP client I&#8217;m pleased to announce http-streams, an HTTP client library for Haskell, using the Snap Framework&#8217;s new io-streams library to handle the streaming I/O. Back and there again I&#8217;ve been doing a lot of work lately using Haskell to do reprocessing of data from various back-end web services and then presenting fragments of [...]]]></description>
				<content:encoded><![CDATA[<h1>An HTTP client</h1>

<p><style type="text/css">
<!--
.lnr { color: #eeeeec; }
.String { color: #204a87; font-weight: bold; }
.Statement { color: #8f5902; font-weight: bold; }
.Identifier { color: #729fcf; }
.hsType { color: #000000; font-weight: bold; }
.hsImport { color: #000000; font-weight: bold; }
.hsImportLabel { color: #73d216; font-weight: bold; }
.hsModuleName { color: #000000; font-weight: bold; }
.Type { color: #73d216; font-weight: bold; }
.Special { color: #ad7fa8; }
.hsLineComment { color: #888a85; }
-->
</style></p>

<p>I&#8217;m pleased to announce <span class="package">http-streams</span>, an HTTP client library for Haskell, using the Snap Framework&#8217;s new <a class="repository" href="https://github.com/snapframework/io-streams">io-streams</a> library to handle the streaming I/O.</p>

<h2>Back and there again</h2>

<p>I&#8217;ve been doing a lot of work lately using Haskell to do reprocessing of data from various back-end web services and then presenting fragments of that information in the specific form needed to drive client-side visualizations. Nothing unusual about that; on one edge of your program you have a web server and on the other you&#8217;re making make onward calls to further servers. Another project includes meshes of agents talking to other agents; again, nothing extreme; just a server daemon responding to requests and in turn making its own requests of others. Fairly common in any environment build on (and in turn offering) RESTful APIs.</p>

<p>I&#8217;m doing my HTTP server work with the fantastic <a href="http://snapframework.com/">Snap Framework</a>; it&#8217;s a lightweight and decently performing web server library with a nice API. To go with that I needed an web client library, but there the choices are less inspiring.</p>

<p>Those working in Yesod have the powerful <a class="package" href="http://hackage.haskell.org/package/http-conduit">http-conduit</a> package, but I didn&#8217;t find it all that easy to work with. I soon found myself writing a wrapper around it just so I could use types and an API that made more sense to me.</p>

<p>Because I was happily writing web apps using Snap, I thought it would be cool to write a client library that would use the same types. After much discussion with Gregory Collins and others, it became clear that trying to reuse the <code>Request</code> and <code>Response</code> types from <a class="package" href="http://hackage.haskell.org/package/snap-core">snap-core</a> wasn&#8217;t going to be possible. But there was a significant amount of code
in Snap&#8217;s test suite, notably almost an entire HTTP client implementation. Having used <code>Snap.Test</code> to build test code for some of my own web service APIs, I knew there was some useful material there, and that gave me a useful starting point.</p>

<h2>Streaming I/O</h2>

<p>One of the exciting things about Haskell is the collaborative way that
boundaries are pushed. From the beginnings in <a class="package" href="http://hackage.haskell.org/package/iteratee">iteratee</a> and <a class="package" href="http://hackage.haskell.org/package/enumerator">enumerator</a>, the
development of streaming I/O libraries such as <a class="package" href="http://hackage.haskell.org/package/conduit">conduit</a> and <a class="package" href="http://hackage.haskell.org/package/pipes">pipes</a> has been phenomenal.</p>

<p>The Snap web server made heavy use of the original iteratee/enumerator paradigm; when I talked to some of the contributors in <code>#snapframework</code> about whether they were planning to upgrade to one of the newer streaming I/O libraries, I discovered from Greg that he and Gabriel were quietly working on a re-write of the internals of the server, based on their experiences doing heavy I/O in production.</p>

<p>This new library is <a class="package" href="http://hackage.haskell.org/package/io-streams">io-streams</a>, aimed at being a pragmatic implementation of some of the impressive theoretical work from the other streaming libraries. <span class="package">io-streams</span>&#8216;s design makes the assumption that you&#8217;re working in &#8230; <code>IO</code>, which seems to have allowed them to make some significant optimizations. The API is <em>really</em> clean, and my early benchmarks were promising indeed.</p>

<p>That was when I realized that being compatible with Snap was less about the <code>Request</code> and <code>Response</code> types and far more about being able to smoothly pass through request and response bodies &#8212; in other words, tightly integrating with the streaming I/O library used to power the web server.</p>

<p><a class="package" href="http://hackage.haskell.org/package/http-streams">http-streams</a>, then, is an HTTP client library built
to leverage and in turn expose an API based on the capabilities of
<span class="package">io-streams</span>.</p>

<h2>A simple example</h2>

<p>We&#8217;ll make a GET request of <a href="http://kernel.operationaldynamics.com:58080/time"><code>http://kernel.operationaldynamics.com:58080/time</code></a> (which is just a tinsy web app which returns the current UTC time). The basic <span class="package">http-streams</span> API is pretty straight forward:</p>

<pre>
<span class="lnr">10 </span>
<span class="lnr">11 </span><span class="Special">{-# LANGUAGE OverloadedStrings #-}</span>
<span class="lnr">23 </span>
<span class="lnr">24 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">System.IO.Streams</span> (<span class="hsType">InputStream</span>, <span class="hsType">OutputStream</span>, <span class="Identifier">stdout</span>)
<span class="lnr">25 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsImportLabel">qualified</span><span class="hsImport"> </span><span class="hsModuleName">System.IO.Streams</span> <span class="hsImportLabel">as</span> <span class="hsModuleName">Streams</span>
<span class="lnr">26 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">Network.Http.Client</span>
<span class="lnr">27 </span>
<span class="lnr">28 </span><span class="Identifier">main</span> <span class="Statement">::</span> <span class="hsType">IO</span> <span class="hsType">()</span>
<span class="lnr">29 </span><span class="Identifier">main</span> <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">30 </span>    c <span class="Statement">&lt;-</span> openConnection <span class="String">&quot;kernel.operationaldynamics.com&quot;</span> 58080
<span class="lnr">31 </span>
<span class="lnr">32 </span>    q <span class="Statement">&lt;-</span> buildRequest <span class="Statement">$</span> <span class="Statement">do</span>
<span class="lnr">33 </span>        http <span class="hsType">GET</span> <span class="String">&quot;/time&quot;</span>
<span class="lnr">34 </span>        setAccept <span class="String">&quot;text/plain&quot;</span>
<span class="lnr">35 </span>
<span class="lnr">36 </span>    sendRequest c q emptyBody
<span class="lnr">37 </span>
<span class="lnr">38 </span>    receiveResponse c (<span class="Statement">\</span>p i <span class="Statement">-&gt;</span> <span class="Statement">do</span>
<span class="lnr">39 </span>        Streams.connect i stdout)
<span class="lnr">40 </span>
<span class="lnr">41 </span>    closeConnection c
<span class="lnr">42 </span>
</pre>

<p>which results in</p>

<pre><code>Sun 24 Feb 13, 11:57:10.765Z
</code></pre>

<h3>Open connection</h3>

<p>Going through that in a bit more detail, given that single import and some code running in <code>IO</code>, we start by opening a connection to the appropriate host and port:</p>

<pre>
<span class="lnr">30 </span>    c <span class="Statement">&lt;-</span> openConnection <span class="String">&quot;kernel.operationaldynamics.com&quot;</span> 58080
</pre>

<h3>Create Request object</h3>

<p>Then you can build up the request you need:</p>

<pre>
<span class="lnr">32 </span>    q <span class="Statement">&lt;-</span> buildRequest <span class="Statement">$</span> <span class="Statement">do</span>
<span class="lnr">33 </span>        http <span class="hsType">GET</span> <span class="String">&quot;/time&quot;</span>
<span class="lnr">34 </span>        setAccept <span class="String">&quot;text/plain&quot;</span>
</pre>

<p>that happens in a nice little state monad called <code>RequestBuilder</code> with a number of simple functions to set various headers.</p>

<p>Having built the <code>Request</code> object we can have a look at what the outbound request would look like over the wire, if you&#8217;re interested. Doing:</p>

<pre>
<span class="lnr">35 </span>    putStr <span class="Statement">$</span> show q
</pre>

<p>would have printed out:</p>

<pre><code>GET /time HTTP/1.1
Host: kernel.operationaldynamics.com:58080
User-Agent: http-streams/0.3.0
Accept-Encoding: gzip
Accept: text/plain
</code></pre>

<h3>Send request</h3>

<p>Making the request is a simple call to <code>sendRequest</code>. It takes the Connection, a Request object, and function of type</p>

<pre>
<span class="lnr">   </span>(<span class="hsType">OutputStream</span> <span class="hsType">Builder</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> <span class="hsType">α</span>)
</pre>

<p>which is where we start seeing the <code>System.IO.Streams</code> types from <span class="package">io-streams</span>. If you&#8217;re doing a PUT or POST you write a function where you are handed the <code>OutputStream</code> and can write whatever content you want to it. Here, however, we&#8217;re just doing a normal GET request which by definition has no request body so we can use <code>emptyBody</code>, a predefined function of that type which simply returns without sending any body content. So:</p>

<pre>
<span class="lnr">36 </span>    sendRequest c q emptyBody
</pre>

<p>gets us what we want. If we were doing a <code>PUT</code> or <code>POST</code> with a request body, we&#8217;d write to the <code>OutputStream</code> in our body function. It&#8217;s an <code>OutputStream</code> of <code>Builder</code>s as a fairly significant optimization; the library will end up chunking 
and sending over an underlying <code>OutputStream ByteString</code> which is wrapped around the socket, but building up the ByteString(s) first in a Builder reduces allocation overhead when smacking together all the small strings that the request headers are composed of; taken together it often means requests will be done in a single <em>sendto(2)</em> system call.</p>

<h3>Read response</h3>

<p>To read the reply from the server you make a call to <code>receiveResponse</code>. Like <code>sendRequest</code>, you pass the Connection and a function to handle the entity body, this time one which will read the response bytes. It&#8217;s type is</p>

<pre>
<span class="lnr">   </span>(<span class="hsType">Response</span> <span class="Statement">-&gt;</span> <span class="hsType">InputStream</span> <span class="hsType">ByteString</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> β)
</pre>

<p>This is where things get interesting. We can use the <code>Response</code> object to find out the status code of the response, read various headers, and deal with the reply accordingly. Perhaps all we care about is the status code:</p>

<pre>
<span class="lnr">42 </span><span class="Identifier">statusHandler</span> <span class="Statement">::</span> <span class="hsType">Response</span> <span class="Statement">-&gt;</span> <span class="hsType">InputStream</span> <span class="hsType">ByteString</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> <span class="hsType">()</span>
<span class="lnr">43 </span><span class="Identifier">statusHandler</span> p i <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">44 </span>    <span class="Statement">case</span> getStatusCode p <span class="Statement">of</span>
<span class="lnr">45 </span>        200 <span class="Statement">-&gt;</span> return <span class="hsType">()</span>
<span class="lnr">46 </span>        _   <span class="Statement">-&gt;</span> error <span class="String">&quot;Bad server!&quot;</span>
</pre>

<p>The response body it available through the <code>InputStream</code>, which is where we take advantage of the streaming I/O coming down from the server. For instance, if you didn&#8217;t trust the server&#8217;s <code>Content-Length</code> header and wanted to count the length of the response yourself:</p>

<pre>
<span class="lnr">42 </span><span class="Identifier">countHandler</span> <span class="Statement">::</span> <span class="hsType">Response</span> <span class="Statement">-&gt;</span> <span class="hsType">InputStream</span> <span class="hsType">ByteString</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> <span class="hsType">Int</span>
<span class="lnr">43 </span><span class="Identifier">countHandler</span> p i1 <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">44 </span>    go 0 i1
<span class="lnr">45 </span>  <span class="Type">where</span>
<span class="lnr">46 </span>    go !acc i <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">47 </span>        xm <span class="Statement">&lt;-</span> Streams.read i
<span class="lnr">48 </span>        <span class="Statement">case</span> xm <span class="Statement">of</span>
<span class="lnr">49 </span>            <span class="hsType">Just</span> x  <span class="Statement">-&gt;</span> go (acc <span class="Statement">+</span> S.length x) i
<span class="lnr">50 </span>            <span class="hsType">Nothing</span> <span class="Statement">-&gt;</span> return acc
</pre>

<p>Ok, that&#8217;s pretty contrived, but it shows the basic idea: when you <code>read</code> from an <code>InputStream a</code> it&#8217;s a sequence of <code>Maybe a</code>; when you get <code>Nothing</code> the input is finished. Realistic usage of <span class="package">io-streams</span> is a bit more idiomatic; the library offers a large range of  functions for manipulating streams, many of which are wrappers to build up more refined streams from lower-level raw ones. In this case, we could do the counting trick using <code>countInput</code> which gives you an action to tell you how many bytes it saw:</p>

<pre>
<span class="lnr">42 </span><span class="Identifier">countHandler2</span> p i1 <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">43 </span>    (i2, getCount) <span class="Statement">&lt;-</span> Streams.countInput i1
<span class="lnr">44 </span>
<span class="lnr">45 </span>    Streams.skipToEof i2
<span class="lnr">46 </span>
<span class="lnr">47 </span>    len <span class="Statement">&lt;-</span> getCount
<span class="lnr">48 </span>    return len
</pre>

<p>For our example, however, we don&#8217;t need anything nearly so fancy; you can of course use the lambda function in-line we showed originally. If you also wanted to spit the response headers out to <code>stdout</code>, <code>Response</code> also has a useful <code>Show</code> instance.</p>

<pre>
<span class="lnr">38 </span>    receiveResponse c (<span class="Statement">\</span>p i <span class="Statement">-&gt;</span> <span class="Statement">do</span>
<span class="lnr">39 </span>        putStr <span class="Statement">$</span> show p
<span class="lnr">40 </span>        Streams.connect i stdout)
</pre>

<p>which is, incidentally, exactly what the predefined <code>debugHandler</code> function does:</p>

<pre>
<span class="lnr">38 </span>    receiveResponse c debugHandler
</pre>

<p>either way, when we run this code, it will print out:</p>

<pre><code>HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Sun, 24 Feb 2013 11:57:10 GMT
Server: Snap/0.9.2.4
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: text/plain

Sun 24 Feb 13, 11:57:10.765Z
</code></pre>

<p>Obviously you don&#8217;t normally need to print the headers like that, but they can certainly be useful for testing.</p>

<h3>Close connection</h3>

<p>Finally we close the connection to the server:</p>

<pre>
<span class="lnr">41 </span>    closeConnection c
</pre>

<p>And that&#8217;s it!</p>

<p>More advanced modes of operation are supported. You can reuse the same connection, of course, and you can also pipeline requests &#91;sending a series of requests followed by reading the corresponding responses in order&#93;. And meanwhile the library goes to some trouble to make sure you don&#8217;t violate the invariants of HTTP; you can&#8217;t read more bytes than the response contains, but if you read <em>less</em> than the length of the response, the remainder of the response will be consumed for you.</p>

<h2>Don&#8217;t forget to use the conveniences before you go</h2>

<p>The above <em>is</em> simple, and if you need to refine anything about the request then you&#8217;re encouraged to use the underlying API directly. However, as often as not you just need to make a request of a URL and grab the response. Ok:</p>

<pre>
<span class="lnr">61 </span><span class="Identifier">main</span> <span class="Statement">::</span> <span class="hsType">IO</span> <span class="hsType">()</span>
<span class="lnr">62 </span><span class="Identifier">main</span> <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">63 </span>    x <span class="Statement">&lt;-</span> get <span class="String">&quot;http://www.haskell.org/&quot;</span> concatHandler
<span class="lnr">64 </span>    S.putStrLn x
</pre>

<p>The <code>get</code> function is just a wrapper around composing a GET request using the basic API, and <code>concatHandler</code> is a utility handler that takes the entire response body and returns it as a single <code>ByteString</code> &#8212; which somewhat defeats the purpose of &#8220;streaming&#8221; I/O, but often that&#8217;s all you want.</p>

<p>There are <code>put</code> and <code>post</code> convenience functions as well. They take a function for specifying the request body and a handler function for the response. For example:</p>

<pre>
<span class="lnr">66 </span>    put "http://s3.example.com/" (fileBody "fozzie.jpg") handler
</pre>

<p>this time using <code>fileBody</code>, another of the pre-defined entity body functions.</p>

<p>Finally, for the ever-present not-going-to-die-anytime-soon <code>application/x-www-form-urlencoded</code> POST request &#8212; everyone&#8217;s favourite &#8212; we have <code>postForm</code>:</p>

<pre>
<span class="lnr">67 </span>    postForm "https://jobs.example.com/" [(<span class="String">&quot;name&quot;</span>,<span class="String">&quot;Kermit&quot;</span>),(<span class="String">&quot;role&quot;</span>,<span class="String">&quot;Stagehand&quot;</span>)] handler
</pre>

<h3>Secure connections</h3>

<p>I&#8217;ve also completely neglected to mention until now SSL support and error handling. Secure connections are supported using <strong>openssl</strong>; if you&#8217;re working in the convenience API you can just request an <code>https://</code> URL as shown above; in the underlying API you call <code>openConnectionSSL</code> instead of <code>openConnection</code>. As for error handling, a major feature of <span class="package">io-streams</span> is that you leverage the existing <code>Control.Exception</code> mechanisms from <span class="package">base</span>; the short version is you can just wrap <code>bracket</code> around the whole thing for any exception handling you might need &#8212; that&#8217;s what the convenience functions do, and there&#8217;s a <code>withConnection</code> function which automates this for you if you want.</p>

<h2>Status</h2>

<p>I&#8217;m pretty happy with the <span class="package">http-streams</span> API at this point and it&#8217;s pretty much feature complete. A fair bit of profiling has been done, and the code is pretty sound at this point. Benchmarks against other HTTP clients are favourable.</p>

<p>After a few years working in Haskell this is my first go at implementing a library as opposed to just writing applications. There&#8217;s a lot I&#8217;ve had learn about writing good library code, and I&#8217;ve really appreciated working with Gregory Collins as we&#8217;ve fleshed out this API together. Thanks also to Erik de Castro Lopo, Joey Hess, Johan Tibell, and Herbert Valerio Riedel for their review and comments.</p>

<p>You can find the API documentation for <a href="http://research.operationaldynamics.com/projects/http-streams/doc/Network-Http-Client.html"><code>Network.Http.Client</code></a> here (until Hackage generates the docs) and the source code at <a class="repository" href="https://github.com/afcowie/http-streams">GitHub</a>.</p>

<p>AfC</p>

<p><em>Updates</em></p>

<ol>
<li>Code snippets updated to reflect API change made to <code>buildRequest</code> as of v0.4.0. You no longer need to pass the Connection object when building a Request.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/haskell/http-streams-introduction/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Railway Signalling</title>
		<link>http://blogs.operationaldynamics.com/andrew/engineering/railways/railway-signalling</link>
		<comments>http://blogs.operationaldynamics.com/andrew/engineering/railways/railway-signalling#comments</comments>
		<pubDate>Sat, 02 Mar 2013 06:51:14 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Railway Engineering]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=874</guid>
		<description><![CDATA[I&#8217;ve long been interested in railways. Not because I&#8217;m a &#8220;foamer&#8221; (UK parlance &#8212; apparently some people foam at the mouth when they get the chance to watch passenger trains move, or so the railway employees would have it) or a &#8220;railfan&#8221; (the US term &#8212; Is that supposed to be like &#8220;sportsfan&#8221;? I mean, [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve long been interested in railways. Not because I&#8217;m a &#8220;foamer&#8221; (UK parlance &#8212; apparently some people foam at the mouth when they get the chance to watch passenger trains move, or so the railway employees would have it) or a &#8220;railfan&#8221; (the US term &#8212; Is that supposed to be like &#8220;sportsfan&#8221;? I mean, just because I want to take a photo that has a train in it doesn&#8217;t make me a weirdo, does it? Apparently), but for the same reason that engineers tend to interested in almost everything: <em>how does it all work?</em></p>

<p><center>
<img src="http://members.iinet.net.au/~judithandrichard/marbelup/p1156771.jpg" alt="Model of a searchlight railway signal" />
<img src="http://members.iinet.net.au/~judithandrichard/marbelup/p1156796.jpg" alt="" /><br />
<i>Not bad for a model railroad!</i>
</center></p>

<p>One part of real-world railways that is fascinating is the signalling necessary to make operations safe and efficient. It&#8217;s beguiling to an engineer in no small part because, by design, you can&#8217;t infer the behaviour of the entire system just watching the signals that go by as you&#8217;re on a train: automated signalling isn&#8217;t just about local conditions, but about the relationships between track conditions and the locations of trains across vast distances. The relevant Wikipedia pages have never been much help, either. As an unrequited model railroader, I&#8217;ve seen plenty of articles about modelling signals, and even descriptions of CTC machines and Train Orders, but still precious little about how <em>signalling systems</em>, as a whole, work. So I&#8217;ve long been curious.</p>

<p>A few days ago I came across a fantastic reference by one <a href="http://www.lundsten.dk/us_signaling/">Carsten Lundsten</a> about how signalling is done in North America. I&#8217;ve been <strong>engrossed</strong>. It appears the site was written somewhat for a European audience, but as far as I can tell it&#8217;s pretty informative for a Canadian and American one, too.</p>

<p>Rather than blathering on about which rule number a signal represents or what speed limits are, these documents concentrate on how signalling systems protect trains and how they have improved over time to provide greater automation and flexibility. If you&#8217;re interested, definitely start with <a href="http://www.lundsten.dk/us_signaling/movement.html">Basics of North American Signaling and Safety principles</a>.</p>

<p><center>
<img src="http://www.lundsten.dk/us_signaling/absdt.gif" alt="Absolute Block Control, double track, through to Centralized Traffic Control, double track" /><br />
<i>Want to know what this means?</i>
</center></p>

<p>Be sure to make your way through to the page about  <a href="http://www.lundsten.dk/us_signaling/abs_apb/index.html">Absolute Permissive Block</a> signalling &#8212; by far and away the best explanation for APB and how APB is different than ABS I&#8217;ve ever seen, and I&#8217;ve been casually researching this for years.</p>

<p><center>
<img src="http://www.lundsten.dk/us_signaling/abs_apb/apb_e7.gif" alt="Opposing signals clearning in section of main track under control of an Absolute Permissive Block signalling system" />
</center></p>

<p>Enjoy, all ye &#8220;train geeks&#8221;.</p>

<p>AfC</p>

<p style="font-size: small;">
Model photos from Richard Stallard&#8217;s site about his <a href="http://members.iinet.net.au/~judithandrichard/marbelup/signals.htm">Marbelup Valley</a> railway.<br />
Signal plant diagrams from Carsten Lundsten&#8217;s site, as above.
</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/engineering/railways/railway-signalling/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Defining OS specific code in Haskell</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/haskell/config-dot-h-and-ifdef</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/haskell/config-dot-h-and-ifdef#comments</comments>
		<pubDate>Wed, 20 Feb 2013 01:04:19 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=837</guid>
		<description><![CDATA[I&#8217;ve got an ugly piece of Haskell code: 213 baselineContextSSL :: IO SSLContext 214 baselineContextSSL = do 215 ctx &#60;- SSL.context -- a completely blank context 216 contextSetDefaultCiphers ctx 217 #if defined __MACOSX__ 218 contextSetVerificationMode ctx VerifyNone 219 #elif defined __WIN32__ 220 contextSetVerificationMode ctx VerifyNone 221 #else 222 contextSetCADirectory ctx &#34;/etc/ssl/certs&#34; 223 contextSetVerificationMode ctx $ [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve got an ugly piece of Haskell code:</p>

<p><style type="text/css">
pre { font-family: monospace; color: #000000; background-color: #ffffff; }
.lnr { color: #eeeeec; }
.hsBlockComment { color: #c4a000; }
.Constant { color: #73d216; }
.Statement { color: #8f5902; font-weight: bold; }
.String { color: #204a87; font-weight: bold; }
.PreProc { color: #f57900; }
.hsImport { color: #000000; font-weight: bold; }
.hsImportLabel { color: #73d216; font-weight: bold; }
.Identifier { color: #729fcf; }
.hsType { color: #000000; font-weight: bold; }
.hsModuleName { color: #000000; font-weight: bold; }
.Type { color: #73d216; font-weight: bold; }
.Special { color: #ad7fa8; }
.hsLineComment { color: #888a85; }
</style></p>

<p><style>
code.filename { font-style: italic; color: green; }
</style></p>

<pre>
<span class="lnr">213 </span><span class="Identifier">baselineContextSSL</span> <span class="Statement">::</span> <span class="hsType">IO</span> <span class="hsType">SSLContext</span>
<span class="lnr">214 </span><span class="Identifier">baselineContextSSL</span> <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr">215 </span>    ctx <span class="Statement">&lt;-</span> SSL.context    <span class="hsLineComment">-- a completely blank context</span>
<span class="lnr">216 </span>    contextSetDefaultCiphers ctx
<span class="lnr">217 </span><span class="PreProc">#if defined __MACOSX__</span>
<span class="lnr">218 </span>    contextSetVerificationMode ctx <span class="hsType">VerifyNone</span>
<span class="lnr">219 </span><span class="PreProc">#elif defined __WIN32__</span>
<span class="lnr">220 </span>    contextSetVerificationMode ctx <span class="hsType">VerifyNone</span>
<span class="lnr">221 </span><span class="PreProc">#else</span>
<span class="lnr">222 </span>    contextSetCADirectory ctx <span class="String">&quot;/etc/ssl/certs&quot;</span>
<span class="lnr">223 </span>    contextSetVerificationMode ctx <span class="Statement">$</span>
<span class="lnr">224 </span>        <span class="hsType">VerifyPeer</span> <span class="hsType">True</span> <span class="hsType">True</span> <span class="hsType">Nothing</span>
<span class="lnr">225 </span><span class="PreProc">#endif</span>
<span class="lnr">226 </span>    return ctx
</pre>

<p>this being necessary because the non-free operating systems don&#8217;t store their X.509 certificates in a place that openssl can reliably discover them. This sounds eminently solvable at lower levels, but that&#8217;s not really my immediate problem; after all, this sort of thing is what <code>#ifdef</code>s are for. The problem is needing to get an appropriate symbol based on what OS you&#8217;re using defined.</p>

<p>I naively assumed there would be <code>__LINUX__</code> and <code>__MACOSX__</code> and <code>__WIN32__</code>
macros already defined by GHC because, well, that&#8217;s just the sort of wishful thinking
that powers the universe.</p>

<p>When I asked the haskell-cafe mailing list for suggestions, Krzysztof Skrzętnicki <a href="http://www.haskell.org/pipermail/haskell-cafe/2013-February/106405.html">said</a> that I could use in my project&#8217;s <code>.cabal</code> file. Nice, but problematic because you&#8217;re not always building using Cabal; you might be working in <code>ghci</code>, you might be using a proper <code>Makefile</code> to build your code, etc. Then Henk-Jan van Tuyl <a href="http://www.haskell.org/pipermail/haskell-cafe/2013-February/106415.html">pointed</a> out that you can get at the Cabal logic care of <a href="http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-System.html#t:OS"><code>Distribution.System</code></a>. Hey, that&#8217;s cool! But that would imply depending on and linking the Cabal library into your production binary. That&#8217;s bad enough, but the even bigger objection is that <em>binaries aren&#8217;t portable</em>, so what&#8217;s the point of having a binary that &#8212; at runtime! &#8212; asks what operating system it&#8217;s on? No; I&#8217;d rather find that out at build time and then let the C pre-processor include only the relevant code.</p>

<p>This feels simple and an appropriate use of CPP; even the symbol names
look just about like what I would have expected (stackoverflow said so,
must be true). Just need to get the right symbol defined at build time. But how?</p>

<h2>Build Types</h2>

<p>Running <code>cabal install</code> one sees all kinds of packages building and I&#8217;d definitely noticed some interesting things happen; some packages fire off what is obviously an autoconf generated <code class="filename">./configure</code> script; others seem to use <code>ghci</code> or <code>runghc</code> to dynamically interpret a small Haskell program. So it&#8217;s obviously do-able, but as is often the case with Haskell it&#8217;s not immediately apparent where to get started.</p>

<p>Lots of libraries available on Hackage come with a top-level <code class="filename">Setup.hs</code>. Whenever I&#8217;d looked in one all I&#8217;d seen is:</p>

<pre>
<span class="lnr">  1 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">Distribution.Simple</span>
<span class="lnr">  2 </span><span class="Identifier">main</span> <span class="Statement">=</span> defaultMain
</pre>

<p>which rather rapidly gave me the impression that this was a legacy of older modules, since running:</p>

<pre><code>$ cabal configure
$ cabal build
$ cabal install
</code></pre>

<p>on a project <em>without</em> a <code class="filename">Setup.hs</code> apparently just Does The Right Thing™.</p>

<p>It turns out there&#8217;s a reason for this. In a project&#8217;s <code>.cabal</code> file, there&#8217;s a field <code>build-type</code> that everyone seems to define, and of course we&#8217;re told to just set this to &#8220;Simple&#8221;:</p>

<pre>
<span class="lnr"> 27 </span><span class="Statement">build-type</span>:          Simple
</pre>

<p>what else would it be? Well, the answer to that is that &#8220;Simple&#8221; is <em>not</em> the default;
&#8220;Custom&#8221; is (really? weird). And a custom build is one where Cabal will compile and invoke <code>Setup.hs</code> when <code>cabal configure</code> is called.</p>

<p>Ahh.</p>

<p>When you look in the documentation of the <a href="http://hackage.haskell.org/package/Cabal/" class="package">Cabal</a> library (note, this is different from the <a href="http://hackage.haskell.org/package/cabal-install" class="package">cabal-install</a> package which makes the <code>cabal</code> executable we end up running) Distribution.Simple indeed has <code>defaultMain</code> but it has friends. The interesting one is <code>defaultMainWithHooks</code> which takes this <a href="http://hackage.haskell.org/packages/archive/Cabal/latest/doc/html/Distribution-Simple.html#t:UserHooks">monster</a> as its argument; sure enough, there are pre-conf, post-conf, pre-build, post-build, and so on; each one is a function which you can easily override.</p>

<pre>
<span class="lnr"> 20 </span><span class="Identifier">main</span> <span class="Statement">::</span> <span class="hsType">IO</span> <span class="hsType">()</span>
<span class="lnr"> 21 </span><span class="Identifier">main</span> <span class="Statement">=</span> defaultMainWithHooks <span class="Statement">$</span> simpleUserHooks {
<span class="lnr"> 22 </span>       postConf <span class="Statement">=</span> configure
<span class="lnr"> 23 </span>    }
<span class="lnr"> 24 </span>
<span class="lnr"> 25 </span><span class="Identifier">configure</span> <span class="Statement">::</span> <span class="hsType">Args</span> <span class="Statement">-&gt;</span> <span class="hsType">ConfigFlags</span> <span class="Statement">-&gt;</span> <span class="hsType">PackageDescription</span> <span class="Statement">-&gt;</span> <span class="hsType">LocalBuildInfo</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> <span class="hsType">()</span>
<span class="lnr"> 26 </span><span class="Identifier">configure</span> <span class="Statement">_ _ _ _ = do</span>
<span class="lnr"> 27 </span>    ...
</pre>

<p>yeay for functions as first class objects. From there it was a simple matter to write some code in my <code>configure</code> function to call Distribution.Simple&#8217;s <code>buildOS</code> and write out a <code class="filename">config.h</code> file with the necessary <code>#define</code> I wanted:</p>

<pre>
<span class="lnr">  1 </span><span class="PreProc">#define __LINUX__</span>
</pre>

<h2>Include Paths</h2>

<p>We&#8217;re not quite done yet. As soon as you want to <code>#include</code> something, you have to start caring about include paths. It would appear the compiler, by default, looks in the same directory as the file it is compiling. Fair enough, but I don&#8217;t really want to put <code class="filename">config.h</code> somewhere deep in the <code class="filename">src/Network/Http/</code> tree; I want to put it in the project&#8217;s top level directory, commonly known as <code class="filename">.</code>, also known as &#8220;where I&#8217;m editing and running everything from&#8221;. So you have to add a <code>-I"."</code> option to <code>ghc</code> invocations in your <code>Makefile</code>s, your <code>.cabal</code> file needs to be told in its way:</p>

<pre>
<span class="lnr"> 61 </span><span class="Type">library</span>
<span class="lnr"> 62 </span>  <span class="Statement">include-dirs</span>:      .
</pre>

<p>and as for <code>ghci</code>, it turns out you can put a <code class="filename">.ghci</code> in your sources:</p>

<pre>
<span class="lnr">  1 </span>:set -XOverloadedStrings
<span class="lnr">  2 </span>:set +m
<span class="lnr">  3 </span>:set -isrc:tests
<span class="lnr">  4 </span>:set -I.
</pre>

<p>and if you put that in your project root directory,  running <code>ghci</code> there will work without having to specify all that tedious nonsense on the command line.</p>

<p>The final catch is that you have to be very specific about where you put the <code>#include</code> directive in your source file. Put it at the top? Won&#8217;t work. After the pragmas? You&#8217;d think. Following the module statement? Nope. It would appear that it strictly has to go <em>after</em> the <code>import</code>s and <em>before</em> any real code. Line 65:</p>

<pre>
<span class="lnr"> 47 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">Data.Monoid</span> (<span class="hsType">Monoid</span> <span class="Identifier">(..)</span>, <span class="Identifier">(&lt;&gt;)</span>)
<span class="lnr"> 48 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsImportLabel">qualified</span><span class="hsImport"> </span><span class="hsModuleName">Data.Text</span> <span class="hsImportLabel">as</span> <span class="hsModuleName">T</span>
<span class="lnr"> 49 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsImportLabel">qualified</span><span class="hsImport"> </span><span class="hsModuleName">Data.Text.Encoding</span> <span class="hsImportLabel">as</span> <span class="hsModuleName">T</span>
<span class="lnr"> 50 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">Data.Typeable</span> (<span class="hsType">Typeable</span>)
<span class="lnr"> 51 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">GHC.Exts</span>
<span class="lnr"> 52 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">GHC.Word</span> (<span class="hsType">Word8</span> <span class="Identifier">(..)</span>)
<span class="lnr"> 53 </span><span class="hsImportLabel">import</span><span class="hsImport"> </span><span class="hsModuleName">Network.URI</span> (<span class="hsType">URI</span> <span class="Identifier">(..)</span>, <span class="hsType">URIAuth</span> <span class="Identifier">(..)</span>, <span class="Identifier">parseURI</span>)
<span class="lnr"> 64 </span>
<span class="lnr"> 65 </span><span class="PreProc">#include </span><span class="String">&quot;config.h&quot;</span>
<span class="lnr"> 66 </span>
<span class="lnr"> 67 </span><span class="Type">type</span> <span class="hsType">URL</span> <span class="Statement">=</span> <span class="hsType">ByteString</span>
<span class="lnr"> 68 </span>
<span class="lnr"> 69 </span><span class="hsLineComment">--</span>
<span class="lnr"> 70 </span><span class="hsLineComment">-- | Given a URL, work out whether it is normal or secure, and then</span>
<span class="lnr"> 71 </span><span class="hsLineComment">-- open the connection to the webserver including setting the</span>
<span class="lnr"> 72 </span><span class="hsLineComment">-- appropriate default port if one was not specified in the URL. This</span>
<span class="lnr"> 73 </span><span class="hsLineComment">-- is what powers the convenience API, but you may find it useful in</span>
<span class="lnr"> 74 </span><span class="hsLineComment">-- composing your own similar functions.</span>
<span class="lnr"> 75 </span><span class="hsLineComment">--</span>
<span class="lnr"> 76 </span><span class="Identifier">establishConnection</span> <span class="Statement">::</span> <span class="hsType">URL</span> <span class="Statement">-&gt;</span> <span class="hsType">IO</span> (<span class="hsType">Connection</span>)
<span class="lnr"> 77 </span><span class="Identifier">establishConnection</span> r' <span class="Statement">=</span> <span class="Statement">do</span>
<span class="lnr"> 78 </span>    ...
</pre>

<p>You get the idea.</p>

<h2>Choices</h2>

<p>Several people wrote to discourage this practice, arguing that conditional code is the wrong approach to portability. I disagree, but you may well have a simple piece of code being run dynamically that would do well enough just making the choice at runtime; I&#8217;d be more comfortable with that if the OS algebraic data type was in base somewhere; linking Cabal in seems rather heavy. Others tried to say that needing to do this at all is openssl&#8217;s fault and that I should be using something else. Perhaps, and I don&#8217;t doubt that we&#8217;ll give <a class="package" href="http://hackage.haskell.org/package/tls">tls</a> a try at some point. But for now, openssl is battle-tested crypto and the <a href="http://hackage.haskell.org/package/HsOpenSSL" class="package">hsopenssl</a> package is a nice language binding and heavily used in production.</p>

<p>Meanwhile I think I&#8217;ve come up with a nice technique for defining things to drive conditional compilation. You can see the complete <code class="filename">Setup.hs</code> I wrote <a class="repository" href="https://github.com/afcowie/http-streams/blob/master/Setup.hs">here</a>; it figures out which platform you&#8217;re on and writes the <code>.h</code> file accordingly. If you have need to do simple portability conditionals, you might give it a try.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/haskell/config-dot-h-and-ifdef/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating Vim and GPG</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/vim-gpg-integration</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/vim-gpg-integration#comments</comments>
		<pubDate>Thu, 15 Nov 2012 00:08:13 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[GNOME Desktop]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=818</guid>
		<description><![CDATA[Quite frequently, I need to take a quick textual note but when the content is sensitive, even just transiently, well, some things shouldn&#8217;t be left around on disk in plain text. Now before you pipe up with &#8220;but I encrypt my home directory&#8221; keep in mind that that only pretects data against it being read [...]]]></description>
				<content:encoded><![CDATA[<p>Quite frequently, I need to take a quick textual note but when the content is sensitive, even just transiently, well, some things shouldn&#8217;t be left around on disk in plain text. Now before you pipe up with &#8220;but I encrypt my home directory&#8221; keep in mind that that only pretects data against it being read in the event your machine is stolen; if something gets onto your system while it&#8217;s powered up and you&#8217;re logged in, the file is there to read.</p>

<p>So for a while my workflow there has been the following rather tedious sequence:</p>

<pre><code>$ vi document.txt
$ gpg --encrypt --armour 
    -r andrew@operationaldynamics.com 
    -o document.asc document.txt
$ rm document.txt
$
</code></pre>

<p>and later on, to view or edit the file,</p>

<pre><code>$ gpg --decrypt -o document.txt document.asc 
$ view document.txt
$ rm document.txt
</code></pre>

<p><em>(yes yes, I could use default behaviour for a few things there, but GPG has a bad habit of doing things that you&#8217;re not expecting; applying the principle of least surprise seems a reasonable defensive measure, but fine, ok</em></p>

<pre><code>$ gpg &lt; document.asc
</code></pre>

<p><em>indeed works. Pedants, the lot of you).</em></p>

<p>Obviously this is tedious, and worse, error prone; don&#8217;t be overwriting the wrong file, now. Far more serious, you have the plain text file sitting around while you&#8217;re working on it, which from an operational security standpoint is completely unacceptable.</p>

<h2>vim plugin</h2>

<p>I began to wonder if there was better way of doing this, and sure enough, via the volumous Vim website I eventually found my way to this delightful gem: <a href="https://github.com/jamessan/vim-gnupg">https://github.com/jamessan/vim-gnupg</a> by James McCoy.</p>

<p>Since it might not be obvious, to install it you can do the following: grab a copy of the code,</p>

<pre><code>$ cd ~/src/
$ mkdir vim-gnupg
$ cd vim-gnupg/
$ git clone git://github.com/jamessan/vim-gnupg.git github
$ cd github/
$ cd plugin/
$ ls
</code></pre>

<p>Where you will see one <code>gnupg.vim</code>. To make Vim use it, you need to put in somewhere <code>vim</code> will see it, so symlink it into your home directory:</p>

<pre><code>$ mkdir ~/.vim
$ mkdir ~/.vim/plugin
$ cd ~/.vim/plugin/
$ ln -s ~/src/vim-gnupg/github/plugin/gnupg.vim .
$
</code></pre>

<p>Of course have a look at what&#8217;s in that file; this is crypto and it&#8217;s important to have confidence that the implementation is sane. Turns out that the <code>gnupg.vim</code> plugin is &#8220;just&#8221; Vim configuration commands, though there are some pretty amazing contortions. People give Emacs a bad rap for complexity, but whoa. <code>:)</code>. The fact you can do all that in Vim is, er, staggering.</p>

<p>Anyway, after all that, it Just Works™. I give my filename a <code>.asc</code> suffix, and ta-da:</p>

<pre><code>$ vi document.asc
</code></pre>

<p>the plugin decrypts, lets me edit clear text in memory, and then re-encrypts before writing back to disk. Nice! For a new file, it prompts for the target address (which is one&#8217;s own email for personal use) and then on it&#8217;s way. &#91;If you&#8217;re instead using symmetrical encryption, I see no way around creating an empty file with <code>gpg</code> first, but other than that, it works as you&#8217;d expect&#93;. Doing all of this on a GNOME 3 system, you already have a <code>gpg-agent</code> running, so you get all the sexy entry dialogs and proper passphrase caching.</p>

<p>I&#8217;m hoping a few people in-the-know will have a look at this and vet that this plugin doing the right thing, but all in all this seems a rather promising solution for quickly editing encrypted files.</p>

<p>Now if we can just convince Gedit to do the same.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/vim-gpg-integration/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java-gnome 4.1.2 released</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/java-gnome/java-gnome-4-1-2-release</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/java-gnome/java-gnome-4-1-2-release#comments</comments>
		<pubDate>Thu, 30 Aug 2012 09:53:21 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[java-gnome]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=808</guid>
		<description><![CDATA[This post is an extract of the release note from the NEWS file which you can read online &#8230; or in the sources from Bazaar. java-gnome 4.1.2 (30 Aug 2012) Applications don&#8217;t stand idly by. After a bit of a break, we&#8217;re back with a second release in the 4.1 series covering GNOME 3 and [...]]]></description>
				<content:encoded><![CDATA[<p><center>
<img src="http://java-gnome.sourceforge.net/images/java-gnome_LargeLogo.png" border="0" width="100" height="107"></center></p>

<p><em>This post is an extract of the release note from the</em> <code>NEWS</code> <em>file which you can read <a href="http://java-gnome.sourceforge.net/NEWS.html">online</a> &#8230; or in the
<a href="http://research.operationaldynamics.com/bzr/java-gnome/mainline/NEWS">sources</a> from Bazaar.</em></p>

<hr />

<h1>java-gnome 4.1.2  (30 Aug 2012)</h1>

<p><em>Applications don&#8217;t stand idly by.</em></p>

<p>After a bit of a break, we&#8217;re back with a second release in the 4.1 series
covering GNOME 3 and its libraries. </p>

<h2>Application for Unique</h2>

<p>The significant change in this release is the introduction of GtkApplication,
the new mechanism providing for unique instances of applications. This
replaces the use of libunique for this purpose, which GNOME has deprecated and
asked us to remove.</p>

<p>Thanks to Guillaume Mazoyer for having done the grunt work figuring out how
the underlying GApplication mechanism worked. Our coverage begins in the <a href="http://java-gnome.sourceforge.net/doc/api/4.1/org/gnome/gtk/Application.html">Application</a> class.</p>

<h2>Idle time</h2>

<p>The new Application coverage doesn&#8217;t work with java-gnome&#8217;s multi-thread
safety because GTK itself is not going to be thread safe anymore. This is a
huge step backward, but has been coming for a while, and despite our intense
disappointment about it all, java-gnome will now be like every other GUI
toolkit out there: not thread safe.</p>

<p>If you&#8217;re working from another thread and need to update your GTK widgets, you
must do so from within the main loop. To get there, you add an idle handler
which will get a callback from the main thread at some future point. We&#8217;ve
exposed that as <a href="http://java-gnome.sourceforge.net/doc/api/4.1/org/gnome/glib/Glib.html#idleAdd(org.gnome.glib.Handler)"><code>Glib.idleAdd()</code></a>; you put your call back in an instance of the
Handler interface.</p>

<p>As with signal handlers, you have to be careful to return from your callback
as soon as possible; you&#8217;re blocking the main loop while that code is running.</p>

<h2>Miscellaneous improvements</h2>

<p>Other than this, we&#8217;ve accumulated a number of fixes and improvements over the
past months. Improvements to radio buttons, coverage of GtkSwitch, fixes to
Assistant, preliminary treatment of StyleContext, and improvements to
SourceView, FileChooser, and more. Compliments to Guillaume Mazoyer, Georgios
Migdos, and Alexander Boström for their contributions.</p>

<p>java-gnome builds correctly when using Java 7. The minimum supported version
of the runtime is Java 6. This release depends on GTK 3.4.</p>

<p>AfC</p>

<hr />

<p><em>You can download java-gnome&#8217;s sources from</em> <a href="http://ftp.gnome.org/pub/GNOME/sources/java-gnome/4.1/"><code>ftp.gnome.org</code></a>, <em>or easily checkout a branch from</em> &#8216;<code>mainline</code>&#8216;<em>:</em></p>

<pre style="background: black; color: white; margin: 10px; padding: 12px;">
$ bzr checkout bzr://research.operationaldynamics.com/bzr/java-gnome/mainline java-gnome
</pre>

<p><em>though if you&#8217;re going to do that you&#8217;re best off following the instructions in the</em> <a href="http://java-gnome.sourceforge.net/HACKING.html"><code>HACKING</code></a> <em>guidelines.</em></p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/java-gnome/java-gnome-4-1-2-release/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing RESTful APIs the not-quite-as-hard way</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/research/testing-restful-apis-with-httpie</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/research/testing-restful-apis-with-httpie#comments</comments>
		<pubDate>Mon, 27 Aug 2012 13:25:06 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=798</guid>
		<description><![CDATA[Last week I wrote briefly about using wget and curl to test RESTful interfaces. A couple people at CERN wrote in to suggest I look at a tool they were quite happy with, called httpie. I&#8217;m impressed. It seems to strike a lovely balance between expressiveness and simplicity. What&#8217;s especially brilliant is that it&#8217;s written [...]]]></description>
				<content:encoded><![CDATA[<p>Last week I wrote briefly about using <a href="http://blogs.operationaldynamics.com/andrew/software/research/testing-rest-the-hard-way">wget and curl to test RESTful interfaces</a>. A couple people at CERN wrote in to suggest I look at a tool they were quite happy with, called <code>httpie</code>.</p>

<p>I&#8217;m impressed. It seems to strike a lovely balance between expressiveness and simplicity. What&#8217;s especially brilliant is that it&#8217;s written for the common case of needing to customize headers and set specific parameters; you can do it straight off the command line. For what I was doing last week:</p>

<pre><code>$ http GET http://localhost:8000/muppet/6 Accept:application/json
...
</code></pre>

<p>sets the Accept header in your request; sending data is unbelieveably easy. Want to post to a form? <code>-f</code> gets you url encoding, and meanwhile you just set parameters on the command line:</p>

<pre><code>$ http -f POST http://localhost:8000/ name="Kermit" title="le Frog"
POST / HTTP/1.1
Accept: */*
Accept-Encoding: gzip
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.2.7

name=Kermit&amp;title=le+Frog
...
</code></pre>

<p>Nice.</p>

<p>If you&#8217;re sending JSON it does things like set the Content-Type and Accept headers to what they should be by simply specifying <code>-j</code> (which sensibly is the default if you POST or PUT and have name=value pairs). And, <code>-v</code> gets you both request and response headers; if you&#8217;re testing at this level you usally want to see both. Good show.</p>

<pre><code>$ http -v -j GET http://localhost:8000/muppet/6
GET /muppet/6 HTTP/1.1
Accept: application/json
Accept-Encoding: gzip
Host: localhost:8000
User-Agent: HTTPie/0.2.7


HTTP/1.1 200 OK
Cache-Control: max-age=42
Content-Encoding: gzip
Content-Type: application/json
Date: Thu, 09 Aug 2012 03:52:27 GMT
Server: Snap/0.9.1
Transfer-Encoding: chunked
Vary: Accept-Encoding

{
    "name": "Fozzie"
    "title": "Bear"
}
$
</code></pre>

<p>Speaking of bears, I&#8217;m afraid to say it turned out to be quite the bear getting httpie installed on Ubuntu. I had to backport <code>pygments</code>, <code>requests</code>, <code>python-oathlib</code>, and <code>pycrypto</code> from Quintal to Precise, and meanwhile the <code>httpie</code> package in Quintal was only 0.1.6; upstream is at 0.2.7 and moving at a rapid clip. I finally managed to get through dependency hell; if you want to try httpie you can add my <a href="https://launchpad.net/~afcowie/+archive/network">network tools PPA</a> as <code>ppa:afcowie/network</code>. I had to make one change to httpie: the default compression header in <code>python-requests</code> is</p>

<pre><code>Accept-Encoding: identity, deflate, compress, gzip
</code></pre>

<p>which is a bit silly; for one thing if the server isn&#8217;t willing to use any of the encodings then it&#8217;ll just respond a normal uncompressed entity, so you don&#8217;t need <code>identity</code>. More importantly, listing <code>deflate</code> and <code>compress</code> before <code>gzip</code> is inadvisable; some servers interpret the order encodings are specified as an order of preference, and lord knows the intersecting set of servers and clients that actually get defalate right is vanishingly small. So,</p>

<pre><code>Accept-Encoding: gzip
</code></pre>

<p>Seems more than sufficient as a <em>default</em>; you can always change it on the command line if you have to for testing. Full documentation at <a href="https://github.com/jkbr/httpie">github</a>; that said, once it&#8217;s installed, <code>http --help</code> will tell you everything you&#8217;d like to know.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/research/testing-restful-apis-with-httpie/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing RESTful APIs the hard way</title>
		<link>http://blogs.operationaldynamics.com/andrew/software/research/testing-rest-the-hard-way</link>
		<comments>http://blogs.operationaldynamics.com/andrew/software/research/testing-rest-the-hard-way#comments</comments>
		<pubDate>Fri, 27 Jul 2012 05:35:11 +0000</pubDate>
		<dc:creator>Andrew Cowie</dc:creator>
				<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://blogs.operationaldynamics.com/andrew/?p=759</guid>
		<description><![CDATA[RESTful APIs tend to be written for use by other programs, but sometimes you just want to do some testing from the command line. This has a surprising number of gotchas; using curl or wget is harder than it should be. Wget Wget is the old standby, right? Does everything you&#8217;d ever want it to. [...]]]></description>
				<content:encoded><![CDATA[<p>RESTful APIs tend to be written for use by other programs, but sometimes you just want to do some testing from the command line. This has a surprising number of gotchas; using curl or wget is harder than it should be.</p>

<h2>Wget</h2>

<p>Wget is the old standby, right? Does everything you&#8217;d ever want it to. Bit of minor tweaking to get it not to blab on stdout about what it&#8217;s resolving (<code>-q</code>) and meanwhile telling it to just print the entity retrieved to stdout rather than saving it to a file (<code>-O -</code>) is easy enough. Finally, I generally like to see the response headers from the server I&#8217;m talking to (<code>-S</code>) so as to check that caching and entity tags are being set correctly:</p>

<pre><code>$ wget -S -q -O - http://server.example.com/resource/1
  HTTP/1.1 200 OK
  Transfer-Encoding: chunked
  Date: Fri, 27 Jul 2012 04:49:17 GMT
  Content-Type: text/plain
Hello world
</code></pre>

<p>So far so good.</p>

<p>The thing is, when doing RESTful work all you&#8217;re really doing is just exercising the <a href="http://tools.ietf.org/html/rfc2616">HTTP spec</a>, admittedly somewhat adroitly. So you need to be able to indicate things like the media type you&#8217;re looking for. Strangely, there&#8217;s no command line option offered by Wget for that; you have to specify the header manually:</p>

<pre><code>$ wget -S -q --header "Accept: application/json" -O - http://server.example.com/resource/1
  HTTP/1.1 200 OK
  Date: Fri, 27 Jul 2012 04:55:50 GMT
  Cache-Control: max-age=42
  Content-Type: application/json
  Content-Length: 27
{
    "text": "Hello world"
}
</code></pre>

<p>Cumbersome, but that&#8217;s what we wanted. Great.</p>

<p>Now to update. This web service wants you to use HTTP PUT to change an existing resource. So we&#8217;ll just figure out how to do that. Reading the man page. Hm, nope; Wget is a downloader. Ok, that&#8217;s what it said it was, but I&#8217;d really come to think of it as a general purpose tool; it <em>does</em> support sending form data up in a POST request with it&#8217;s <code>--post-file</code> option. I figured PUT would just be lurking in a hidden corner. Silly me.</p>

<h2>Curl</h2>

<p>Ok, howabout Curl? Doing a GET is dead easy. Turn on response headers for diagnostic purposes (<code>-i</code>), but Curl writes to stdout by default, so:</p>

<pre><code>$ curl -i http://server.example.com/resource/1
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Fri, 27 Jul 2012 05:11:00 GMT
Content-Type: text/plain

Hello world
</code></pre>

<p>but yup, we&#8217;ve still got to mess around manually supplying the MIME type we want; at least the option (<code>-H</code>) is a bit tighter:</p>

<pre><code>$ curl -i -H "Accept: application/json" http://server.example.com/resource/678
HTTP/1.1 200 OK
Date: Fri, 27 Jul 2012 05:12:32 GMT
Cache-Control: max-age=42
Content-Type: application/json
Content-Length: 27

{
    "text": "Hello world"
}
</code></pre>

<p>Good start. Ok, what about our update? It&#8217;s not obvious from the curl man page, but to PUT data with curl, you have to manually specify the HTTP method to be used with (<code>-X</code>) and then (it turns out) you use the same <code>-d</code> parameter as you would if you were transmitting with POST:</p>

<pre><code>$ curl -X PUT -d name=value http://server.example.com/resource/1
$
</code></pre>

<p>That&#8217;s nice, except that when you&#8217;re PUTting you generally are not sending &#8220;<code>application/x-www-form-urlencoded</code>&#8221; name/value pairs; you&#8217;re sending actual content. You can tell Curl to pull from a file:</p>

<pre><code>$ curl -X PUT -d @filename.data http://server.example.com/resource/1
</code></pre>

<p>or, (at last), from stdin like you&#8217;d actually expect of a proper command line program:</p>

<pre><code>$ curl -X PUT -d @- http://server.example.com/resource/1
You are here.
And then you aren't.
^D
$
</code></pre>

<p>That was great, except that I found all my newlines getting stripped! I looked in in the database, and the content was:</p>

<pre><code>You are here. And then you aren't.
</code></pre>

<p>Bah.</p>

<p>After writing some tests server-side to make sure it wasn&#8217;t my code or the datastore at fault, along with finally resorting to <code>hexdump -C</code> to find out what was going on, I finally discovered that my trusty <code>\n</code> weren&#8217;t being stripped, they were being <em>converted</em> to <code>\r</code>. Yes, that&#8217;s right, mind-numbingly, <strong>Curl performs newline conversion</strong> by default. Why oh why would it do that?</p>

<p>Anyway, it turns out that <code>-d</code> is short for <code>--data-ascii</code>; the workaround is to use <code>--data-binary</code>:</p>

<pre><code>$ curl -X PUT --data-binary @- http://server.example.com/resource/1
</code></pre>

<p>&#8220;oh,&#8221; he says, underwhelmed. But it gets better; for reasons I don&#8217;t yet understand, Curl gets confused by EOF )as indicated by typing <strong><code>Ctrl+D</code></strong> in the terminal). Not sure what&#8217;s up with that, but trusty 40 year-old <code>cat</code> knows what to do, so use it as a front end:</p>

<pre><code>$ cat | curl -X PUT --data-binary @- http://server.example.com/resource/1
Goodbye
^D
$
</code></pre>

<p>The other thing missing is the MIME type you&#8217;re sending; if for example you&#8217;re sending a representation in JSON, you&#8217;ll need a header saying so:</p>

<pre><code>$ cat filename.json |
    curl -X PUT --data-binary @-
    -H "Content-Type: application/json" http://server.example.com/resource/1
{
    "text": "Goodbye cruel world"
}
^D
$
</code></pre>

<p>which is all a bit tedious. Needless to say I&#8217;ve stuck that in a shell script called (with utmost respect to libwww-perl) <code>PUT</code>, taking content type as an argument:</p>

<pre><code>$ ./PUT "application/json" http://localhost:8000/resource/1 &lt; filename.json
HTTP/1.1 204 Updated
Server: Snap/0.9.1
Date: Fri, 27 Jul 2012 04:53:53 GMT
Cache-Control: no-cache
Content-Length: 0
$
</code></pre>

<p>Ah, that&#8217;s more like it.</p>

<p>AfC</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.operationaldynamics.com/andrew/software/research/testing-rest-the-hard-way/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
