<?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>subbu.org &#187; HTTP</title>
	<atom:link href="http://www.subbu.org/blog/category/http/feed" rel="self" type="application/rss+xml" />
	<link>http://www.subbu.org</link>
	<description></description>
	<lastBuildDate>Sun, 05 Feb 2012 20:12:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>ql.io: Consuming HTTP at Scale</title>
		<link>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale</link>
		<comments>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale#comments</comments>
		<pubDate>Wed, 25 Jan 2012 01:08:03 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1719</guid>
		<description><![CDATA[Slides from my workshop on ql.io at the Node Summit. ql.io: Consuming HTTP at Scale View more presentations from Subbu Allamaraju]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fql-io-consuming-http-at-scale"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fql-io-consuming-http-at-scale&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Slides from my workshop on ql.io at the Node Summit.</p>
<div style="width:425px" id="__ss_11244206"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/sallamar/qlio-consuming-http-at-scale" title="ql.io: Consuming HTTP at Scale " target="_blank">ql.io: Consuming HTTP at Scale </a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/11244206" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/sallamar" target="_blank">Subbu Allamaraju</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Idempotency Matters</title>
		<link>http://www.subbu.org/blog/2012/01/idempotency-matters</link>
		<comments>http://www.subbu.org/blog/2012/01/idempotency-matters#comments</comments>
		<pubDate>Mon, 16 Jan 2012 09:29:45 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1666</guid>
		<description><![CDATA[Here is an example of how idempotency can save end users a precious second or so. Several weeks ago, one of the teams using ql.io reported that they were seeing random socket hang up errors in server logs. error: { stack: [Getter&#47;Setter], arguments: undefined, type: undefined, message: &#39;socket hang up&#39;, uri: { value: &#39;http:&#47;&#47;clientalerts.ebay.com&#47;...&#39; The [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fidempotency-matters"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fidempotency-matters&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Here is an example of how idempotency can save end users a precious second or so.</p>
<p><span id="more-1666"></span></p>
<p>Several weeks ago, one of the teams using <a href="http://ql.io">ql.io</a> reported that they were seeing random socket hang up errors in server logs.</p>
<pre><code>error: { stack: [Getter&#47;Setter],
 arguments: undefined,
 type: undefined,
 message: &#39;socket hang up&#39;,
 uri:
  { value: &#39;http:&#47;&#47;clientalerts.ebay.com&#47;...&#39;
</code></pre>
<p>The source of this log was the <code>error</code> handler of the http client</p>
<pre><code>request = http.request(...);
request.on(&#39;error&#39;, function(err) {
    &#47;&#47; log the error
});
</code></pre>
<p>This error was so random that we could not find a reproducer on our dev or testing environments for a while. We then wrote a ql.io script that emulates the production use case, ran that script using <a href="http://www.joedog.org/index/siege-home">siege</a> to emulate the production usage, and captured the traffic using tcpdump. While we were to able to capture a few instances of socket hang up errors with this setup, the tcpdump did not give definite answers as there were too much data to sift through. The client (siege) was making requests in parallel to a cluster of node instances with each instance maintaining its own socket pool. But there were two clues:</p>
<ul>
<li>The origin was closing the connection after some usage by sending a FIN packet, but none of the accompanying HTTP responses included the <code>Connection: close</code> header. This is quite common as connection handling is often done at the reverse proxy tier which may not insert this header in the last response before closing the connection.</li>
<li>The number of new connections opened during the test was a few less than the number of connections closed. This indicates that some requests were being made on closed connections causing the socket hang up errors.</li>
</ul>
<p>This lead us to <a href="https://github.com/joyent/node/issues/1135">Issue 1135</a> &#8211; a timing related issue in node.js where inflight requests made by the client after the FIN packet was sent caused the socket hang up error. The resolution was to retry the request if possible.</p>
<p>HTTP GET, PUT and DELETE requests are retriable in case of such network errors, and the server implementations of these methods are supposed to support such retries.</p>
<p>But here is the rub. There is a lot of bad deployed HTTP server code out in the wild that might choke when a client retries in case of such network errors. Hence, node.js can not retry automatically without some indication from the client application. In the end, we decided to retry the request when an idempotent HTTP request caused by a <a href="http://ql.io/docs/select">select</a> statement encounters network failures such as the above. This helped us save an extra roundtrip from the client to ql.io.</p>
<p>This is a reminder of why idempotency is a necessary promise to keep in HTTP server code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2012/01/idempotency-matters/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>APIs are a Pain</title>
		<link>http://www.subbu.org/blog/2011/11/apis-are-a-pain</link>
		<comments>http://www.subbu.org/blog/2011/11/apis-are-a-pain#comments</comments>
		<pubDate>Fri, 18 Nov 2011 23:16:16 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1556</guid>
		<description><![CDATA[I don&#8217;t like writing client apps that use APIs. Writing HTTP client code to talk to APIs is verbose, repetitive, chatty and slow. This is in addition to addressing latency and bandwidth constraints and core functionality of the client app &#8211; such as building a snappy UI or supporting some other business use case. First [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F11%2Fapis-are-a-pain"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F11%2Fapis-are-a-pain&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I don&rsquo;t like writing client apps that use APIs. Writing HTTP client code to talk to APIs is verbose, repetitive, chatty and slow. This is in addition to addressing latency and bandwidth constraints and core functionality of the client app &ndash; such as building a snappy UI or supporting some other business use case.</p>
<p><span id="more-1556"></span></p>
<p><strong>First &ndash; the interface mismatch.</strong> APIs are almost always designed from the producer&rsquo;s point of view. If I&rsquo;m building an API, I would look at my data model, my performance/scalabilty requirements, and design the API to meet the use cases that I think are the most common across all consumers my of my API. That is, my goal would be to maximize the use and reuse of my API. In this process, I am bound to tradeoff special requirements of my consumers and try to stick to a common denominator. This creates a mismatch between what the consumer needs and what I&rsquo;m offering. Here is an example.</p>
<blockquote><p>A client app needs to search a list of products to get their IDs, some details and some user generated content like reviews for each product. There are three APIs that the client needs to interact with to get this data &ndash; one to search products, one to get details for each product, and another to get reviews for each product.</p>
</blockquote>
<p>This is not a made up or hypothetical example. What the client needs is this.</p>
<blockquote><p>A single API, that takes a keyword, and returns certain fields for each product found &ndash; no more or no less.</p>
</blockquote>
<p>What the client got are three APIs that give some data that includes what the client needs plus some more. The API design makes sense for the producers of these APIs &ndash; search folks are focused on indexing and serving low latecny results, the details API wants to serve all the gazillion details that are relevant to products, and the reviews API wants to focus on low latency writes and potentially stale reads. But, for the consumer, an ideal interface is one that gives just the fields it needs with one single request.</p>
<p><strong>Second &ndash; writing client code is slow, repetitive and verbose</strong>. For the above example, here is what the client needs to do:</p>
<ul>
<li>Call the search API to find products, and extract product IDs from the response.</li>
<li>Call the details API <code>n</code> times &ndash; once per product ID &ndash; to get the details, and then extract the fields needed from the response</li>
<li>Call the reviews API <code>n</code> times  &ndash; once per product ID &ndash; to get reviews, and the extract the fields needed from the response</li>
</ul>
<p>Unless you got canned SDKs for these APIs, writing code to make <code>2*n</code> HTTP requests and process the responses can take a while. In one of the Java implementations I looked at, the code was over 300 lines long &ndash; that was after excluding the request making and response parsing code which was already factored into into supporting libraries. If the client needs to implement ten such use cases, you got 3000 lines of code just doing data retrieval.</p>
<p><strong>Third &ndash; Getting enhancements you need from producer teams slows you down</strong>. For my example above, having a bulk API for details and reviews simplifies the client to some extent. But for both good and bad reasons, API changes that the clients need don&rsquo;t happen immediately. They take time, usually some sprints. Sometimes never. The reality is that teams have their own priorities. Getting a single API for the above won&#8217;t likely happen!</p>
<p><strong>Fourth &ndash; requests for use cases like this are chatty.</strong> Three hundred lines of code may not be a big deal, but making so many HTTP requests is. Here is a common evolution of an implementation. To simplify the discussion, let&rsquo;s assume that we have bulk APIs for details and reviews.</p>
<p><em>Take 1:</em> Use blocking IO to make <code>3</code> HTTP requests.</p>
<p><img src="http://www.subbu.org/images/bio.png" alt="BIO" /></p>
<p>Code complexity of this implementation may be low, but it takes <code>sum(t)</code> where <code>t</code> is the time for each API request.</p>
<p><em>Take 2:</em> If latency is a concern, parallelize the requests. After the search API returns product IDs, you can make <code>2</code> requests in parallel and join the responses.</p>
<p><img src="http://www.subbu.org/images/parallel.png" alt="Parallel" /></p>
<p>Code complexity now increases, but it only takes <code>t1 + max(t)</code> for the whole retrieval, where <code>t1</code> is the time taken to search.</p>
<p>Now imagine that the client needs to call yet another API based on review IDs.</p>
<p><em>Take 3:</em> Orchestrate the retrieval based on dependencies.</p>
<p><img src="http://www.subbu.org/images/dance.png" alt="Painful dance" /></p>
<p>In another example I&rsquo;ve seen recently, a native app makes 17 HTTP requests with some dependencies before painting the UI. The code is over 3000 lines long! Of a team of 3 developers, one developer is dedicated to writing and maintaining this code.</p>
<p>Now move the client farther from the API servers. In addition to the code complexity, the client will have to deal with cost of the network. You may want to move all the request dance to some middle tier that is closer to the API servers than the client.</p>
<p><img src="http://www.subbu.org/images/middle.png" alt="Middle tier" /></p>
<p><strong>Fifth &ndash; consistent RESTful APIs don&rsquo;t matter as much as we think.</strong> I would love to see every API to be RESTful, consistent, hypertext driven, and more importantly, interoperable. The reality is that getting consistent APIs is hard &ndash; particularly those that are done by distributed teams. For the record &#8211; I vehemently hate SOAP APIs and the SOAP mindset. I dislike RPC-style operation names tunneled over HTTP. I frown and cringe whenever I see unnecessary custom headers and complicated formats. I wish POST+XML goes away. I wish every API gets rewritten to the modern understanding of HTTP and REST, serving JSON.</p>
<p>But I would rather spend my time enabling interoperability than preaching for consistency.</p>
<p>Hypermedia does not help either. Hypermedia can help navigation among resources, but navigation is not a concern in the above use case. The client app&rsquo;s challenges are aggregation, parallelization, and orchestration of forks and joins.</p>
<p>So, what can we do about it?</p>
<p><img src="http://farm4.static.flickr.com/3208/2884743046_b2e1aafc9f.jpg" width="500" height="334"></p>
<p>Why would I write a long blog post if I have nothing to offer?</p>
<p>I&rsquo;m excited to reveal that, at eBay, my team has been working on a new platform to simplify use cases like the above:</p>
<ul>
<li>Bring down number of lines of code to call APIs</li>
<li>Automatically orchestrate API calls as needed</li>
<li>Create new consumer-centric APIs that wrap existing producer-centric APIs</li>
<li>Cut down bandwitdh usage and latency</li>
</ul>
<p><span style="text-decoration: line-through;">Best of all, this platform will soon be on github. If you are interested in taking a sneak peek and want to provide feedback, please email me (subbu/at/subbu/dot/org) with your github ID.</span> <em>Please see <a href="http://ql.io">ql.io</a> for more info.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/11/apis-are-a-pain/feed</wfw:commentRss>
		<slash:comments>63</slash:comments>
		</item>
		<item>
		<title>WebSocket Fallbacks</title>
		<link>http://www.subbu.org/blog/2011/11/websocket-fallbacks</link>
		<comments>http://www.subbu.org/blog/2011/11/websocket-fallbacks#comments</comments>
		<pubDate>Wed, 16 Nov 2011 14:02:28 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1544</guid>
		<description><![CDATA[For a soon-to-open sourced nodejs based platform that I have been working on since June this year, I needed a way to send some optional telemetry data back to the browser without mixing it with the real data that the client code is interested in. The first thing I looked at was socket.io. Socket.io&#8217;s claim [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F11%2Fwebsocket-fallbacks"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F11%2Fwebsocket-fallbacks&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>For a soon-to-open sourced nodejs based platform that I have been working on since June this year, I needed a way to send some optional telemetry data back to the browser without mixing it with the real data that the client code is interested in. The first thing I looked at was <a href="http://socket.io">socket.io</a>. Socket.io&#8217;s claim to fame is that it aims to &#8220;make real-time apps possible in every browser and mobile device&#8221;. But it comes at certain cost that may not be apparent. Since then I gave up on socket.io and switched to the plain <a href="http://dev.w3.org/html5/websockets/">WebSocket API</a> on the client side and <a href="https://github.com/Worlize/WebSocket-Node">WebSocket-Node</a> on the server. Here is why.</p>
<p>Cross browser WebSocket fallback is a fallacy. Such fallbacks exist because WebSocket support in browsers continues to limp and the spec itself is not done yet. Interoperability among browsers is not yet possible due to lack of protocol parity. For instance, about a month ago, I had to forego supporting Safari in favor of better experience in latest versions of Chrome and Firefox. But what&#8217;s wrong with fallbacks?</p>
<p>WebSocket interactions are bound to a connection &#8211; once the client opens a TCP connection, it can send and receive several messages using the WebSocket API. But with fallback approaches that rely on JSONP, XHR and iframes, clients and servers use HTTP for serializing messages.</p>
<p>Therein lies a key difference. With the WebSocket protocol, you can scope any state for the duration of the connection and remain state free across connections. For instance if you want to send some events as they occur to the browser, you can associate the subscription state with the socket. You don&#8217;t need to replicate that subscription state across all the server nodes that are serving WebSocket traffic. This makes horizontal scalability possible.</p>
<p>Not so with HTTP based fallbacks where every message could potentially come in over a different TCP connection.  To account for this you either need to pin the client to a given node so that the same node handles all connections from a client, or replicate state across all the nodes serving the HTTP traffic. socket.io does the latter by using Redis. Consequently you end up trading off reliability and/or scalability.</p>
<p>This leads to my next point &#8211; if scalability is your concern, graceful degradation may just be sufficient in a lot of use cases. You can use feature detection in browsers to decide whether to use WebSocket protocol or not. Here is a simple approach I now use on the client side.</p>
<p><script src="https://gist.github.com/1370108.js?file=gistfile1.txt"></script></p>
<p>This helps me offer a degraded user experience when WebSocket support is not available, and I don&#8217;t have to introduce shared state on the server.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/11/websocket-fallbacks/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Measuring REST</title>
		<link>http://www.subbu.org/blog/2011/08/measuring-rest-2</link>
		<comments>http://www.subbu.org/blog/2011/08/measuring-rest-2#comments</comments>
		<pubDate>Sun, 21 Aug 2011 16:48:17 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1531</guid>
		<description><![CDATA[These are the slides from my talk yesterday at restfest.]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F08%2Fmeasuring-rest-2"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F08%2Fmeasuring-rest-2&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>These are the slides from my talk yesterday at restfest.</p>
<p><iframe src="http://docs.google.com/viewer?url=https%3A%2F%2Fgithub.com%2Fs3u%2Ftalks%2Fraw%2Fmaster%2Fmeasuring-rest-restfest-2011.pdf&#038;embedded=true" width="600" height="470" style="border: none;"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/08/measuring-rest-2/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Performance of RESTful Apps</title>
		<link>http://www.subbu.org/blog/2011/03/performance-of-restful-apps</link>
		<comments>http://www.subbu.org/blog/2011/03/performance-of-restful-apps#comments</comments>
		<pubDate>Fri, 04 Mar 2011 19:08:43 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1416</guid>
		<description><![CDATA[A while ago I showed how chatty some well-known apps are on my iPhone. But this issue is neither new nor unique to apps on phones and similar devices. Efficient data retrieval from distributed/decentralized servers is a well-recognized problem in distributed computing. For instance, in the abstract of his November 1994 paper A Note on [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F03%2Fperformance-of-restful-apps"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F03%2Fperformance-of-restful-apps&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>A while ago I <a href="http://www.subbu.org/blog/2011/01/chatty-apps">showed</a> how chatty some well-known apps are on my iPhone. But this issue is neither new nor unique to apps on phones and similar devices. Efficient data retrieval from distributed/decentralized servers is a well-recognized problem in distributed computing. For instance, in the abstract of his November 1994 paper <a href="http://labs.oracle.com/techrep/1994/abstract-29.html">A Note on Distributed Computing</a>, <a href="http://www.eecs.harvard.edu/~waldo/">Jim Waldo</a> notes the following (emphasis mine).</p>
<blockquote>
<p>We argue that objects that interact in a distributed system need to be dealt with in ways that are intrinsically different from objects that interact in a single address space. These differences are required because distributed systems require that the programmer be aware of <strong>latency</strong>, have a different model of <strong>memory access</strong>, and take into account issues of <strong>concurrency</strong> and <strong>partial failure</strong>.</p>
</blockquote>
<p><span id="more-1416"></span></p>
<p>Most front-end developers by now know and follow the <a href="http://developer.yahoo.com/performance/rules.html">best practices</a> that Yahoo!&#8217;s <a href="http://developer.yahoo.com/performance/">Exceptional Performance</a> team documented a few years ago. However, the REST community may have missed the bus and has some catching up to do. Performance of RESTful Apps is not one of the most frequently talked about topics online or in print. From talking to various teams, it often seems that a great deal of time is spent on <a href="http://my.safaribooksonline.com/9780596809140/75">URI</a>/<a href="http://my.safaribooksonline.com/9780596809140/45">representation</a> design, schemas, use of the <a href="http://my.safaribooksonline.com/9780596809140/1">uniform interface</a> for CRUD, using the <a href="http://my.safaribooksonline.com/9780596809140/87">hypertext constraint</a> etc. No doubt &#8211; these topics are all very important, but understanding and accounting for the performance characteristics in the design and implementation of server and client apps is no less crucial.</p>
<p>Here are some techniques to help build high-performance RESTful apps.</p>
<h2>Composites for Performance</h2>
<p>The best of all web performance techniques is to <a href="http://developer.yahoo.com/performance/rules.html#num_http">minimize the number of HTTP requests</a>. However, RESTful Apps rarely follow this practice. This difference stems from how each side sees resources.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/fe-vs-apis.png" alt="Front-end vs APIs/services"/></p>
<p>On one side, front-end folks optimize their servers to serve bulk representations for CSS, JavaScript or image sprites, or even <a href="http://googlecode.blogspot.com/2010/11/instant-previews-under-hood.html">data URIs for images</a> to reduce the number of HTTP requests and thereby latency. On the front-end, most resources are in fact composites.</p>
<p>On the other side, API/service developers prefer <em>clean looking</em> resources and URIs (shown on the right side above). Though this can lead to chatty network usage, there is one specific advantage in offering a set of resources that are independent and less coupled with other resources &#8211; <strong>it leaves room for clients to innovate</strong>. It lets them combine data from multiple resources in numerous ways that the resource developers could not possibly think of.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/apis-possibilities.png" alt="Many possibilities"/></p>
<p>Loose coupling is another benefit of this approach, as clients can evolve rapidly on their own.</p>
<p>The expense is of course latency, particularly when those client apps are not very close to the servers. Each client may need to submit several requests to the server in order get its job done. So, how do we go about fixing this without sacrificing the flexibility of less-coupled resources?  One answer is to use composite resources. See my <a href="http://my.safaribooksonline.com/book/web-development/web-services/9780596809140/identifying-resources/34">RESTful Web Services Cookbook</a> for details.</p>
<p>With a composite, in stead of sending <code>n</code>-number of HTTP requests over <code>1-n</code> connections, the client can open just one TCP connection to send an HTTP request to retrieve the data it needs &#8211; just like a browser getting CSS or Javascript bundles in the front-end. A composite changes a pattern like</p>
<pre><code>GET /something HTTP/1.1
Host: www.example.org

GET /something-else?params HTTP/1.1
Host: www.example.org

GET /some-other-thing-related-to-something?params HTTP/1.1
Host: www.example.org
</code></pre>
<p>to</p>
<pre><code>GET /get-all-things-i-need-about-something?params HTTP/1.1
Host: www.example.org
</code></pre>
<p>Each composite can generate a projection of state required for one or more clients. These composites can be more specialized than the resources they aggregate &#8211; as each composite can cater to particular client needs.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/composite.png" alt="Many possibilities"/></p>
<p>(P.S.: My usage of the term &quot;resource&quot; is not precise here as a &quot;composite&quot; is also a resource.)</p>
<p>This approach also shifts issues related to concurrency (such as ordering of requests based on success or failure), CPU (for generating projections, correlating related data from across representations etc.) and I/O (to fetch back-end resource representations in a serial/parrallel fashion depending on dependencies) workloads from the client to the server.</p>
<p>On the server side, the server hosting composites can also optimize its connection handling to resource servers to reduce TCP handshake and slowstart overhead. For instance, it can maintain pools of persistent/long-lasting connections (e.g., with <code>keep-alive</code>) between servers hosting composites and the resources (shown by bold arrows above).</p>
<p>In this post, I&#8217;m not going to discuss software choices to serve composites, but you may need to account for several features:</p>
<ul>
<li>multi-tenancy or isolation of code execution, configuration and deployment so that different teams can build composites</li>
<li>data or control flow for fetching representations in parallel or sequentially based on inter-dependencies</li>
<li>query languages (such as <a href="http://developer.yahoo.com/yql/console/">YQL</a>) to normalize data formats and to easily create projections</li>
<li>non-blocking or asynchronous I/O to better tackle I/O workloads</li>
</ul>
<p>I&#8217;m personally excited about <a href="http://nodejs.org/">nodejs</a> and async I/O support in Java 7 as both would let us build small and nimble broker apps to serve composites.</p>
<p>Of course &#8211; the idea of a composite is to add an extra layer of indirection on the server side to offset network overhead when performance is at stake. It is not meant to replace loosely coupled resources that can be manipulated using HTTP and linked using hypertext controls like links in representations.</p>
<h2>Better Connection Reuse</h2>
<p>Long-lasting TCP connections help reduce connection-establishment overhead as well as help the TCP stack settle to appropriate congestion window size. Reusing connections is usually trivial, and pooling is often part of client libraries. But there are a few precautions to take at the application level.</p>
<h3>Avoid Explicit Connection Closing</h3>
<pre><code># Don't do this
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1234
Connection: close

{ ... body ... }
</code></pre>
<p>The first precaution to take is not to add <code>Connection: close</code> to requests or responses by default. Carelessly adding this header to requests or responses will prevent connection reuse. There better be a good reason to add this header such as a server that can&#8217;t handle too many open connections, or to prevent abuse.</p>
<h3>Avoid Close Delimited Messages</h3>
<pre><code># Avoid this
HTTP/1.1 200 OK
Content-Type: application/json

{ ... body ... }
</code></pre>
<p>Make sure to include <code>Content-Length</code> or use <code>Transfer-Encoding: chunked</code> so that the recipient of a HTTP message can know when one HTTP request/response message ends and when the next one starts. If a response has neither of these two, then the recipient will need to read the stream till the connection is closed, which means that the connection cannot be reused. Close-delimited HTTP request/response messages are bad for performance.</p>
<h3>Read Messages Completely</h3>
<p>Incomplete reads will also prevent reuse of the connection. Incomplete reads usually happen when a client receives an error or a redirect response. These kinds of responses can have a body but clients can determine what to do by just looking at the response line and headers. For instance, a <code>409</code> response may have a body that explains why.</p>
<pre><code>HTTP/1.1 409 Conflict
Content-Type: text/html
Content-Length: 1234

&lt;html&gt; ... &lt;/html&gt;
</code></pre>
<p>But not reading the body from the connection my prevent reuse in some frameworks &#8211; Java is <a href="http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html">known</a> for this. Also be wary of libraries that translate <code>4xx</code> and <code>5xx</code> response code into exceptions &#8211; in this case, in addition to catching the exception, the client will need to read the body.</p>
<h3>Tune Idle Connection Timeouts</h3>
<p>Servers and clients usually close idle connections upon a timeout to conserve resources. Settings for idle connection timeout may be hard to find or even not exposed in client/server frameworks. When tuning is possible, ensure that the defaults are reasonable.</p>
<h3>Try Proxies for Long-Haul Traffic</h3>
<p>In some cases a configuration like the following can help:</p>
<p><img src="http://www.subbu.org/uploads/2011/03/proxy-short-lived.png" alt="Proxies for short-lived apps"/></p>
<ul>
<li>Client apps that are short-living (like an app on a mobile/tablet or even on desktops), and hence connections can&#8217;t be persistent. Instead, the proxy can keep connections persistent which limits connection establishment cost to the first leg from client app to the nearest proxy.</li>
<li>Client apps that can&#8217;t maintain too many persistent connections &#8211; which is still the case for browsers today &#8211; though it is slowly changing.</li>
</ul>
<p>Of course, this approach also lets the server <a href="http://www.mnot.net/blog/2006/05/16/web_2_caching">distribute</a> responses to caches on those proxies to further reduce network cost. Many variations of this approach are possible depending on how your servers are distributed and how far are client apps from servers. If you&#8217;re new to the idea of REST and are still wondering why HTTP&#8217;s uniform interface is such a big deal, here is why &#8211; once you implement HTTP reasonably correctly, you can reconfigure servers, proxies and caches as necessary without code changes.</p>
<h2>Progressive Serving of Representations</h2>
<p>Sometimes it is not the network, but generating a response is the bottleneck. This is particularly true for composite resources or resources that rely on a number of data sources to generate a response to the client. The typical flow in such cases is as follows:</p>
<ul>
<li>read the request data such as the path and query string</li>
<li>decide what to fetch</li>
<li>fetch data from each dependent source in sequence or concurrently to the extent possible (which depends on dependencies)</li>
<li>prepare data for the response</li>
<li>write the data to the response</li>
</ul>
<p>Of these steps, when I/O for dependent sources is done sequentially, the server takes at least <code>n*t</code> time to generate a response. If all the I/O can be done in parallel, it takes <code>max(t)</code> amount of time, i.e, it performs at least as slow as the slowest source.</p>
<p>On the front-end side, when it takes time to generate a page, a common practice is to turn to <code>XMLHttpRequest</code> or <code>iframe</code>s to split the page into fragments and defer loading of slower parts of the page. Both these techniques potentially use additional connections. In a multi-tiered setup, this causes a flood of new requests from the browser to front-end servers, and from there to backend servers and so on. This also introduces new state management and security problems as the server may need to push state first to the browser only to get it back via <code>XMLHttpRequest</code> immediately.</p>
<p>An alternative is to progressively render the page over a single connection. In this case, the flow would be</p>
<ul>
<li>read the request data such as the path and query string</li>
<li>decide what to fetch</li>
<li><em>fetch data from fast sources</em></li>
<li><em>initiate requests for slow sources</em></li>
<li><em>serve partial page based on response from fast sources</em></li>
<li><em>as and when a slow source responds, prepare a partial response and write to the client</em></li>
<li><em>after all the sources respond (or after some timeout), write additional chunks and finally end the page</em></li>
</ul>
<p>Here, by &#8220;chunk&#8221; I mean &#8220;part of a message&#8221; and not an HTTP chunk.</p>
<p>The goal of this technique is to reduce user-perceived latency without using more network connections from the browser. In this flow, browser makes an HTTP request to the front-end server which writes snippets of markup and script over a period of time before ending the response. Since the server does not know the <code>Content-Length</code> of the page, it would use <code>chunked</code> transfer encoding where end of response is triggered by a zero-sized chunk.</p>
<p>This is called &#8220;progressive rendering&#8221;. This technique is well-known in front-end circles and Facebook calls this technique <a href="http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919">BigPipe</a>. Progressive rendering depends on two things:</p>
<ul>
<li>Server being able to write chunks over lasting connections &#8211; asynchronous I/O based servers like <a href="http://nodejs.org/">nodejs</a> are very attractive for this (see my nodejs <a href="http://www.subbu.org/blog/2010/07/bigpipe-done-in-node-js">example</a> or <a href="http://www.olympum.com">Bruno</a>&#8216;s <a href="http://www.olympum.com/java/facebook-bigpipe-in-an-async-servlet/">example</a> using continuations).</li>
<li>Clients being able to process response as it arrives &#8211; in Javascript capable browsers, this capability is already present.</li>
</ul>
<p>We can apply this technique for non-front-end resources as well provided (a) it is possible to retrieve data from fast sources before slow resources, and (b) data from fast sources is meaningful to clients. For instance, think of a personalized product resource that includes data about a product plus IDs, links, and brief summaries of related products. In this case, product data can be looked up from storage under a near-constant time (say, about 20 milliseconds) while finding related products may involve performing some computations on the user profile, past purchase history and other derived data which can be time consuming &#8211; say, taking up to 500 milliseconds. Here is an example of a progressive representation of such a product resource.</p>
<pre><code>HTTP/1.1 200 OK
Content-Type: multipart/mixed; boundary=abcdef
Transfer-Encoding: chunked

--abcdef
Content-Type: application/json

{ ... product data here ... }

--abcdef
Content-Type: application/json

{ ... related products here ... }
--abcdef--
</code></pre>
<p>In this example I used a multipart media type as it provides a visible boundary between different portions of the representations, and the client can read the representation part by part. </p>
<p>If the client is a front-end app that generates an HTML product page for browsers, it can progressively render the product page as soon as it receives the first part, and then render markup for list of related products when the second part arrives.</p>
<pre><code>HTTP/1.1 200 OK
Content-Type: text/html
Transfer-Encoding: chunked

&lt;html&gt;
  &lt;head&gt;...&lt;/head&gt;
  &lt;body&gt;
    ... HTML for the product data ...

    &lt;div id="related"&gt;&lt;/div&gt;

    &lt;!-- script for related products (some milliseconds later) --&gt;
    &lt;script&gt; // update related div ...&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This shows how progressive generation of arbitrary representations can be combined with progressive serving of the front-end to reduce perceived latency.</p>
<h2>Epilogue</h2>
<p>One of the patterns to notice from this post is that design considerations between HTML serving front-end apps and JSON/XML/whatever-speaking RESTful apps are not entirely different. Both rely on the same set of core architectural principles such as the uniform interface, visibility, hypertext, and so on. Whatever lessons we learn on the front end are certainly applicable for the so-called API servers.</p>
<p>Finally, it goes without saying that premature optimization is evil. My goal of this post is to point out the techniques you may already have in your toolkit. Apply them based on the need and experimentation.</p>
<p><em>If you find this post useful, try my book: <a href="http://www.amazon.com/gp/product/0596801688?ie=UTF8&#038;tag=cyclogzcom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0596801688">RESTful Web Services Cookbook</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/03/performance-of-restful-apps/feed</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Web Apps and Web Sites</title>
		<link>http://www.subbu.org/blog/2011/02/web-apps-and-web-sites</link>
		<comments>http://www.subbu.org/blog/2011/02/web-apps-and-web-sites#comments</comments>
		<pubDate>Fri, 25 Feb 2011 17:08:38 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1393</guid>
		<description><![CDATA[I just caught up with the recent reactions to the &#8220;hashbang&#8221; episode. Of all the reactions, I&#8217;m most intrigued by Ben Cherry&#8216;s post. Ben&#8217;s point is that the Web has been slowly transforming from &#8220;traditional web sites&#8221; into &#8220;desktop-class applications&#8221; served via HTTP, and that &#8220;the hashbang is in the unfortunate position of being the [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F02%2Fweb-apps-and-web-sites"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F02%2Fweb-apps-and-web-sites&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I just caught up with the recent reactions to the &#8220;hashbang&#8221; episode. Of all the reactions, I&#8217;m most intrigued by <a href="http://www.adequatelygood.com/2011/2/Thoughts-on-the-Hashbang">Ben Cherry</a>&#8216;s post. Ben&#8217;s point is that the Web has been slowly transforming from &#8220;traditional web sites&#8221; into &#8220;desktop-class applications&#8221; served via HTTP, and that &#8220;the hashbang is in the unfortunate position of being the messenger&#8221; of this transformation. He then goes on to make this case:</p>
<blockquote>
<p>We&#8217;ve made a tradeoff, however, in making twitter.com into an application using the hash, which is that it now cannot be both an app and a site at the same time.</p>
</blockquote>
<p>This argument is not uncommon but is troubling. We hear similar arguments from web developers who find it hard to maintain proper browser back-button behavior, or to make case for &#8220;single page apps&#8221; (thank goodness &#8211; Web 2.0 days are behind us), or when some site resets the state of its pages when some in-memory sessions time out. These are all bad for the user. In all these cases, interoperability and usability of the Web suffers. Web works by agreeing on a number of interoperable protocols and formats so that we can code agents, servers and intermediaries to interpret those protocols and provide a consistent behavior to users. Branding a site as an &#8220;app&#8221; should not automatically lead to trading off usability and more importantly, interoperability. </p>
<p><span id="more-1393"></span></p>
<p>Are web apps different from web sites? Yes if you are the developer of the app, but no if you are a user. If you&#8217;re a developer trying to provide rich functionality packed in a single page, the differences between serving a static and typically linear HTML pages, and a complex user interface with code tied to UI/UA events are significant. But hey, we should not make usability arguments wearing a developer hat. Try a user hat and think from the user&#8217;s point of view. For a user, there is just one Web. Users &#8220;logon to the web&#8221; to get stuff done. They don&#8217;t care about the tech choices we need to make to provide rich interactivity.</p>
<p>What&#8217;s the real tradeoff in the hashbang case? The tradeoff here is between usability of two classes of clients &#8211; one that does not support Javascript and the other that supports. That&#8217;s a reasonable tradeoff! Twitter chose to not render <a href="http://twitter.com">http://twitter.com</a> for non-Javascript browsers. Perhaps they made that by choice by looking at the proportion of users that use non-Javascript browsers.</p>
<p>In the case of Twitter, as Ben notes, HTML5 History API can help &#8211; <em>but only partly</em>. Servers like Gawker have also chosen to encode page identity into the <a href="http://tools.ietf.org/html/rfc3986#section-3.5">fragment</a> portion of URIs &#8211; This is a shame. For instance, two <code>GET</code> requests from my command line</p>
<pre><code>curl -v http://gawker.com/
curl -v http://gawker.com/\#\!5769800 # escaped hashbang
</code></pre>
<p>come back with the same response from the server (except for some timestamps and headers). If I have a forward-proxy cache in front of my clients, it unnecessarily fills up the cache with duplicate responses. A big deal? May be or may be not. The point of Web is interoperability. Lack of interoperability forbids serendipitous reuse. Branding a site as an app is an unnecessary distraction.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/02/web-apps-and-web-sites/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Can Pipelining Help?</title>
		<link>http://www.subbu.org/blog/2011/02/can-pipelining-help</link>
		<comments>http://www.subbu.org/blog/2011/02/can-pipelining-help#comments</comments>
		<pubDate>Mon, 07 Feb 2011 06:16:12 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1366</guid>
		<description><![CDATA[HTTP pipelining is often suggested as a way to dramatically improve page load times, or to solve multi-GET use cases for RESTful applications. Whether pipelining can achieve the intended effect or not truly depends on what gets pipelined and how the server implements pipelining. When using pipelining, a HTTP client sends idempotent HTTP requests (such [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F02%2Fcan-pipelining-help"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F02%2Fcan-pipelining-help&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>HTTP pipelining is often suggested as a way to <a href="http://en.wikipedia.org/wiki/HTTP_pipelining">dramatic</a>ally improve page load times, or to solve <a href="http://stackoverflow.com/questions/109343/batching-in-rest">multi-GET use cases</a> for RESTful applications. Whether pipelining can achieve the intended effect or not truly depends on what gets pipelined and how the server implements pipelining. </p>
<p>When using pipelining, a HTTP client sends idempotent HTTP requests (such as <code>GET</code>) without waiting for response of previous requests, and expects responses to arrive in the same order from the server. <a href="http://tools.ietf.org/html/rfc2616">HTTP 1.1</a> says nothing about order of processing of requests on the server side &#8211; servers can process each request in sequence or in parallel. All that matters is the order of responses. However, in the real-world, pipelining is not often used due to a number of interoperability issues. Mark Nottingham recently captured some of these issues in an <a href="http://tools.ietf.org/html/draft-nottingham-http-pipeline">internet draft</a>:</p>
<p><span id="more-1366"></span></p>
<blockquote>
<p>Anecdotal evidence suggests there are a number of reasons why clients don&#8217;t use HTTP pipelining by default.  Briefly, they are:</p>
<ol>
<li>Server implementations may stall pipelined requests, or close their connection. This is one of the most commonly cited problems.</li>
<li>Server implementations may pipeline responses in the wrong order.  Some implementations mix up the order of pipelined responses; e.g., when they hit an error state but don&#8217;t &#8220;fill&#8221; the response pipeline with a corresponding representation.</li>
<li>A few server implementations may corrupt pipelined responses.  It&#8217;s been said that a very small number of implementations actually interleave pipelined responses so that part of response A appears in response B, which is both a security and interoperability problem.</li>
<li>Clients don&#8217;t have enough information about what is useful to pipeline.  A given response may take an inordinate amount of time to generate, and/or be large enough to block subsequent responses.  Clients who pipeline may face worse performance if they stack requests behind such an expensive request.</li>
</ol>
</blockquote>
<p>Even if we fix all the interoperability issues (such as 1, 2, and 3 above), pipelining <a href="http://devcentral.f5.com/weblogs/macvittie/archive/2009/04/02/http-pipelining-a-security-risk-without-real-performance-benefits.aspx">will not</a> necessarily improve anything. Unlike non-pipelined requests, clients need to know a bit about the server&#8217;s implementation before deciding to pipeline requests. Here is why.</p>
<p>The key constraint in pipelining is that the server must send responses in order. This leads to the so-called <a href="http://en.wikipedia.org/wiki/Head-of-line_blocking">head-of-line blocking</a> problem. </p>
<p>Assume that the client opens a connection and sends three <code>GET</code> requests, <code>g1</code>, <code>g2</code>, and <code>g3</code>. Of these, let&#8217;s say that <code>g1</code> takes longer to process than <code>g2</code> and <code>g3</code>. But the server is still required to return responses in the sequence of <code>g1</code>, <code>g2</code>, and <code>g3</code>. Here is one possible implementation in a multi-threaded server.</p>
<ul>
<li>Server receives a connection, and it gives the associated channel/stream to a thread <code>t0</code></li>
<li>Server starts parsing the data in <code>t0</code></li>
<li>Server finds <code>g1</code>, and hands it off to an application handler <code>h1</code> in thread <code>t1</code></li>
<li>Server finds <code>g2</code>, and hands it off to an application handler <code>h2</code>in thread <code>t2</code></li>
<li>Server finds <code>g3</code>, and hands it off to an application handler <code>h3</code> in thread <code>t3</code></li>
<li><code>h2</code> finishes first and wants to write response &#8211; server blocks it since <code>h1</code> has not finished yet</li>
<li><code>h3</code> finishes next and wants to write response &#8211; server blocks it too since <code>h1</code> has not finished yet</li>
<li><code>h1</code> wants to write response &#8211; since <code>g1</code> is the first request, the server lets it</li>
<li>Server unblocks <code>h2</code>, and it writes response</li>
<li>Server unblocks <code>h3</code>, and it writes it to response</li>
</ul>
<p>In this model, the server explicitly blocks application handlers from writing response until it is their turn. Alternative implementations are possible:</p>
<ol>
<li>
<p>The server can wait to read the next request (i.e., the request line, headers and any body) until the previous request is completely processed.  </p>
</li>
<li>
<p>The server can buffer responses of application handlers (at least of those that finish earlier than previous requests) and write them in order to the client.</p>
</li>
</ol>
<p>Over some limited tests during the weekend, I found that both <a href="http://www.jboss.org/netty">Netty</a> and <a href="http://tomcat.apache.org/">Tomcat</a> follow the first approach while <a href="http://nodejs.org/">Nodejs</a> follows the second approach. Both approaches have their limitations, in particular when one of the requests early in the pipeline takes time to complete. In such cases, the client is better off sending <code>g1</code> over one connection, and pipeline <code>g2</code> and <code>g3</code> on a second connection. This will reduce the serialization window on the server. However, in order to make such a choice, the client needs to have some prior idea about workloads involved in processing each request. When such information is difficult to assert (e.g., for a browser sending requests to an arbitrary servers), connection reuse via <code>keep-alive</code> is safer bet than pipelining. In any case, it is better to test before enabling pipelining in clients.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/02/can-pipelining-help/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Referer FUD</title>
		<link>http://www.subbu.org/blog/2011/01/referer-fud</link>
		<comments>http://www.subbu.org/blog/2011/01/referer-fud#comments</comments>
		<pubDate>Mon, 31 Jan 2011 04:37:06 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1364</guid>
		<description><![CDATA[Gabriel Wienberg: For those of you who have no idea what I&#8217;m talking about: when you click on a link on the Internet, where you clicked from gets automatically sent to the site you clicked on (most of the time). For example, if you&#8217;re on yahoo.com and you click to a story at the New [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Freferer-fud"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Freferer-fud&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.gabrielweinberg.com/blog/2011/01/search-leakage-is-not-fud-google-et-al-please-fix-it.html">Gabriel Wienberg</a>:</p>
<blockquote>
<p>For those of you who have no idea what I&#8217;m talking about: when you click on a link on the Internet, where you clicked from gets automatically sent to the site you clicked on (most of the time). </p>
<p>For example, if you&#8217;re on yahoo.com and you click to a story at the New York Times, your browser will send to newyorktimes.com some information that you came from yahoo.com &#8212; namely, the Web address of the page you were just on. This info is called the Referrer.</p>
<p>At issue here is that sometimes the Referrer contains personal information. In particular, when you use most search engines, your search terms are included in the Referrer. That is, when you search on Google/Bing/etc., and you click on a link, your search terms are sent to the site you clicked on. This search leakage doesn&#8217;t happen at DuckDuckGo.</p>
</blockquote>
<p>I don&#8217;t see why this should not be called FUD. This post does not actually explain how any personally identifiable information (PII) leaks to third parties when you search for something using a search engine. Search terms don&#8217;t constitute PII. <a href="http://www.duckduckgo.com">Duck Duck Go</a> uses a <a href="http://gregable.com/2011/01/referrer-stripping.html">clever trick</a> to get the browser send a <code>Referer</code> header with no search terms, but <a href="http://www.subbu.org/blog/2010/10/referer-leak">there are other tricks</a> possible.</p>
<p>At the core, the problem is not with the <code>Referer</code> header. By choice or by poor design, some sites include PII in URIs of pages that link to third-parties. That is the real problem. This is not a problem for Google or Bing to fix. Every site that cares about privacy of its users should just ensure not to leak PII in URIs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/01/referer-fud/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Save 60% on RESTful Web Services Cookbook</title>
		<link>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook</link>
		<comments>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook#comments</comments>
		<pubDate>Tue, 18 Jan 2011 22:35:21 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1360</guid>
		<description><![CDATA[O&#8217;Reilly will be offering the ebook version of the RESTful Web Services Cookbook on sale tomorrow (Jan 19, 2011). Here is the scoop I just received from O&#8217;Reilly. Save 60% &#8211; Top 25 of 2010 Best of Ebook Deal of the Day &#8211; http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g For one day only, you can save 60% on our best [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fsave-60-on-restful-web-services-cookbook"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fsave-60-on-restful-web-services-cookbook&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>O&#8217;Reilly will be offering the ebook version of the <a href="http://www.restful-webservices-cookbook.org">RESTful Web Services Cookbook</a> on sale tomorrow (Jan 19, 2011). Here is the scoop I just received from O&#8217;Reilly.</p>
<blockquote>
<p>Save 60% &#8211; Top 25 of 2010</p>
<p>Best of Ebook Deal of the Day &#8211; <a href="http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g">http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g</a></p>
<p>For one day only, you can save 60% on our best of &#8220;Ebook Deal of the Day&#8221; titles &#8211; the top 25 of 2010. Ebooks from oreilly.com are DRM-free. You get free lifetime access, multiple file formats, and free updates. One day only. Use discount code <strong>DDT25</strong> in the shopping cart. </p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

