<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEYFSH0ycCp7ImA9WhBbEE0.&quot;"><id>tag:blogger.com,1999:blog-7715485</id><updated>2013-05-08T02:41:59.398-07:00</updated><category term="freestyle" /><category term="thisisbroken" /><category term="sysadmin" /><category term="bug" /><category term="latex" /><category term="measurement" /><category term="data tags" /><category term="hash" /><category term="privacy" /><category term="icici" /><category term="interfaces" /><category term="sed" /><category term="chrome" /><category term="ip" /><category term="rhel" /><category term="redhat" /><category term="audio" /><category term="ydn" /><category term="byte order" /><category term="entities" /><category term="esmtp" /><category term="rss" /><category term="thoughts" /><category term="email" /><category term="unicode" /><category term="freebsd" /><category term="xss" /><category term="developer" /><category term="stoyan" /><category term="mathjax" /><category term="blogger template" /><category term="gradient" /><category term="localisation" /><category term="opera" /><category term="iit" /><category term="thisisfixed" /><category term="cmc" /><category term="fidelity" /><category term="scripting" /><category term="facebook" /><category term="i18n" /><category term="authentication" /><category term="wifi" /><category term="theme" /><category term="movable type" /><category term="geo" /><category term="memory" /><category term="webdu" /><category term="pdf" /><category term="australia" /><category term="c" /><category term="mvc" /><category term="creative" /><category term="2fa" /><category term="ui" /><category term="bandwidth" /><category term="flickr" /><category term="delicious" /><category term="programming style" /><category term="design" /><category term="mp3" /><category term="network" /><category term="codepo8" /><category term="statistics" /><category term="ubuntu" /><category term="velocity" /><category term="talks" /><category term="json" /><category term="google" /><category term="berlin" /><category term="mail" /><category term="education" /><category term="4.01-strict" /><category term="smtp" /><category term="firesheep" /><category term="dom" /><category term="planet" /><category term="macosx" /><category term="perl" /><category term="messaging" /><category term="colours" /><category term="bcp" /><category term="ports" /><category term="latency" /><category term="LC_TIME" /><category term="two factor auth" /><category term="png" /><category term="site" /><category term="dhtml" /><category term="toc" /><category term="epicondylitis" /><category term="sigdashes" /><category term="badges" /><category term="howtos" /><category term="webkit" /><category term="opensource" /><category term="ios" /><category term="dynamic script node" /><category term="shell" /><category term="rfc2822" /><category term="nodejs" /><category term="credit card" /><category term="ipc" /><category term="usability" /><category term="comments" /><category term="recovery" /><category term="hack" /><category term="shell script" /><category term="extensions" /><category term="gdb" /><category term="login" /><category term="workaround" /><category term="cookies" /><category term="crockford" /><category term="luhn" /><category term="sockets" /><category term="endianness" /><category term="startup" /><category term="yslow" /><category term="web services" /><category term="widgets" /><category term="ie" /><category term="montreal" /><category term="regex" /><category term="self extracting tarball" /><category term="unix" /><category term="twitter" /><category term="closure" /><category term="wav" /><category term="missing kids" /><category term="server" /><category term="mathematics" /><category term="groupon" /><category term="ip address" /><category term="foss" /><category term="att" /><category term="media queries" /><category term="caching" /><category term="lsm" /><category term="gmail" /><category term="ipv6" /><category term="mobile" /><category term="iso8601" /><category term="nexus" /><category term="boomerang" /><category term="fc9" /><category term="meetup" /><category term="flot" /><category term="dopplr" /><category term="html5" /><category term="web" /><category term="bof" /><category term="YQL" /><category term="printing" /><category term="puzzle" /><category term="fosdem" /><category term="date" /><category term="webtiming" /><category term="phone" /><category term="freedom" /><category term="firefox" /><category term="accessibility" /><category term="iphone" /><category term="css" /><category term="tips" /><category term="favicon" /><category term="performance" /><category term="webdev" /><category term="cron" /><category term="review" /><category term="safari" /><category term="notes" /><category term="broken" /><category term="sydney" /><category term="scalability" /><category term="mysql" /><category term="jabber" /><category term="security" /><category term="keynote" /><category term="webcam" /><category term="typing" /><category term="function currying" /><category term="cracker" /><category term="geek" /><category term="algorithm" /><category term="sendmail" /><category term="compile" /><category term="hacker" /><category term="microformats" /><category term="segfault" /><category term="timezone" /><category term="android" /><category term="filesystem" /><category term="whois" /><category term="vint cerf" /><category term="html" /><category term="ssl" /><category term="partition" /><category term="regular expressions" /><category term="testing" /><category term="acer" /><category term="comic strip" /><category term="w3c" /><category term="strftime" /><category term="yui" /><category term="ephemeral ports" /><category term="dragdrop" /><category term="couchdb" /><category term="url" /><category term="yahoo" /><category term="csrf" /><category term="name generator" /><category term="javascript" /><category term="passwords" /><category term="starttls" /><category term="im" /><category term="load" /><category term="fedora" /><category term="conference" /><category term="http" /><category term="curl" /><category term="hardy" /><category term="rfc3339" /><category term="MAC" /><category term="form" /><category term="gnome" /><category term="spoofing" /><category term="prerender" /><category term="tim berners-lee" /><category term="transactions" /><category term="confoo" /><category term="toy" /><category term="airport wifi" /><category term="cms" /><category term="internet" /><category term="forms" /><category term="roundtrip" /><category term="404" /><category term="progressive enhancement" /><category term="stubbornella" /><category term="database" /><category term="apache" /><category term="linux" /><category term="crash" /><category term="innerHTML" /><category term="soap" /><category term="php" /><category term="programming" /><category term="htc" /><category term="communication" /><category term="bbc" /><category term="instant messaging" /><category term="blog" /><category term="book" /><category term="API" /><category term="ayttm" /><category term="X" /><category term="secnet" /><category term="tcp" /><category term="blogger" /><category term="write performance" /><category term="george" /><category term="foss.in" /><category term="tablespace" /><category term="slideshare" /><category term="everybuddy" /><category term="error checking" /><category term="sampling" /><category term="db" /><title>The other side of the moon</title><subtitle type="html">/bb|[^b]{2}/&lt;br&gt;
Never stop Grokking</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://tech.bluesmoon.info/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>132</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/bluestech" /><feedburner:info uri="bluestech" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/3.0/" /><entry gd:etag="W/&quot;A0ABR34ycSp7ImA9WhBQFk4.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-2877228100902784325</id><published>2013-03-18T13:48:00.002-07:00</published><updated>2013-03-18T13:49:16.099-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-18T13:49:16.099-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="interfaces" /><category scheme="http://www.blogger.com/atom/ns#" term="design" /><category scheme="http://www.blogger.com/atom/ns#" term="ayttm" /><category scheme="http://www.blogger.com/atom/ns#" term="ui" /><title>Reducing checkboxes</title><content type="html">&lt;p&gt;
Alex Limi has an excellent &lt;a href="http://limi.net/checkboxes-that-kill"&gt;post on the overuse of checkboxes&lt;/a&gt; in Firefox's preferences screen.  It reminded me of something Nat mentioned during his talk with Miguel de Icaza back at &lt;a href="http://linux-bangalore.org/2003/"&gt;Linux Bangalore 2003&lt;/a&gt; about Gnome.  They mentioned several UI idioms including checkboxes and disabled menu items, but the gist of it was, every time you give the user a decision to make, you're making their lives harder.  As the domain expert for this product, it's your job to pick sane defaults and not bother the user with these choices.
&lt;/p&gt;
&lt;p&gt;
We took this to heart on the &lt;a href="http://ayttm.sourceforge.net/"&gt;Ayttm&lt;/a&gt; project.  At the time ayttm probably had over 200 user modifiable configuration options in the preferences screen, and each plugin could add its own.  It was way past the point of violating one of our primary design requirements, that it should be easy enough for &lt;a href="http://www.colino.net/wordpress/bienvenue/"&gt;Colin&lt;/a&gt;'s mum to use.  We had a bit of a dilemma though.  While our target audience was definitely non technical, we had a significant number of geeky early adopters who really wanted the ability to modify everything.
&lt;/p&gt;
&lt;p&gt;
Over the next few days we stripped out almost every configurable option from the Preferences screen, however, we left them all in the config file on disk.  Any user that really wanted to modify the options could edit the config file in their favourite text editor and make the changes themselves.  This made everyone happier.  Our technical users were happy that they didn't have to click through too many screens to change all their options, and our non technical users had a preferences screen where the most they'd have to do was enter their account information, and the type of &lt;a href="http://ayttm.sourceforge.net/smileys/"&gt;smileys&lt;/a&gt; they wanted.
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="https://developer.gnome.org/hig-book/stable/"&gt;Gnome Human Interface Guidelines&lt;/a&gt; cover a lot about designing intuitive interfaces, so go read that.
&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7LztvjlTvy4:g6kSwEJTwuQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7LztvjlTvy4:g6kSwEJTwuQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7LztvjlTvy4:g6kSwEJTwuQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7LztvjlTvy4:g6kSwEJTwuQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7LztvjlTvy4:g6kSwEJTwuQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/7LztvjlTvy4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/2877228100902784325/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2013/03/reducing-checkboxes.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2877228100902784325?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2877228100902784325?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/7LztvjlTvy4/reducing-checkboxes.html" title="Reducing checkboxes" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2013/03/reducing-checkboxes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EBQno-cCp7ImA9WhBTGUs.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-2615594449229141159</id><published>2013-02-01T09:41:00.000-08:00</published><updated>2013-02-15T15:07:33.458-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-15T15:07:33.458-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="2fa" /><category scheme="http://www.blogger.com/atom/ns#" term="nexus" /><category scheme="http://www.blogger.com/atom/ns#" term="phone" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="android" /><title>Nexus 4 — First impressions</title><content type="html">&lt;p&gt;
Just got a Nexus 4.  Started it up, and tried to sign in to my gmail account.  I have two-factor auth set up for extra security, and you'd expect a google device to work well with google auth, but here's a list of bugs I've found within minutes of opening the package.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It first asks you to sign in to your gmail account.  Type in your username and password.&lt;/li&gt;
&lt;li&gt;It then tells you you need to sign in on the web to continue, so it opens the browser for you to sign in.&lt;/li&gt;
&lt;li&gt;Focus is on the username field, but there's no keyboard available.  You need to tap on the username field (which already has focus) to bring up the keyboard.  This is counter-intuitive.&lt;/li&gt;
&lt;li&gt;Type in your username and password and submit.  It then takes you to the &lt;abbr title="2 Factor Auth"&gt;2FA&lt;/abbr&gt; page (at least in my case) where you enter your security code.&lt;/li&gt;
&lt;li&gt;Again, tap on the field to bring up the keyboard.  This field is a numeric field, but the keyboard starts out in alphabetic mode.  This is probably a bug with all mobile devices, but you'd think that something this new would have fixed it.&lt;/li&gt;
&lt;li&gt;Type in the code, and now try to click on the checkbox that says "Remember this device".  Except the keyboard goes away and you now end up clicking a link that explains what 2FA is.&lt;/li&gt;
&lt;li&gt;Ok, cool, I just want to go back and hit submit... except there's no back button on this browser.  There's no toolbar that normally pops up at the bottom of the browser.  No, this is a special browser that does not allow you to navigate through the browser history.  FAIL.&lt;/li&gt;
&lt;li&gt;The only way forward is to shut down the phone and then start it up again.  Except at this point you start from scratch, including selecting your language.
&lt;/ol&gt;
&lt;p&gt;
A few other things I've noticed...
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The timezone by default appears to be UTC.  You'd think that it'd localise this based on my location, which it knows and is configured to use.&lt;/li&gt;
&lt;li&gt;If a transient alert message pops up, and you try to tap on it, you'll actually tap on the item below the message.&lt;/li&gt;
&lt;li&gt;The icons are a bit too small for someone with normal sized fingers like me.  It's easy to tap on the wrong item.&lt;/li&gt;
&lt;li&gt;The position of the power button and volume control buttons means that when you press the power button with your thumb, your forefinger will inadvertently hit the volume control (or vice-versa).  This happens because of Newton's third law of motion.  Google/LG engineers should know this since it's a 300 year old basic law of motion.&lt;/li&gt;
&lt;li&gt;You cannot move a widget from one screen to another by dragging it.  You have to remove it from the old screen and then go through the process of adding and configuring it again for the new screen.&lt;/li&gt;
&lt;li&gt;When you select punctuation on the keyboard, entering an apostrophe should switch back to alphabetic mode.  It doesn't.&lt;/li&gt;
&lt;li&gt;It just reboots at times.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Will post more as I use it.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=R4tItBukxaE:yteSB9x18Ds:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=R4tItBukxaE:yteSB9x18Ds:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=R4tItBukxaE:yteSB9x18Ds:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=R4tItBukxaE:yteSB9x18Ds:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=R4tItBukxaE:yteSB9x18Ds:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/R4tItBukxaE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/2615594449229141159/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2013/02/nexus-4-first-impressions.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2615594449229141159?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2615594449229141159?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/R4tItBukxaE/nexus-4-first-impressions.html" title="Nexus 4 &amp;mdash; First impressions" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2013/02/nexus-4-first-impressions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANQXY4fyp7ImA9WhNWEkQ.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-7001500025860906590</id><published>2012-12-11T23:03:00.000-08:00</published><updated>2012-12-11T23:03:10.837-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-11T23:03:10.837-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="caching" /><category scheme="http://www.blogger.com/atom/ns#" term="latency" /><title>A correlation between load time and usage</title><content type="html">We frequently see reports of website usage going up as load time goes down, or vice-versa.  It seems logical.  Users use a site much more if it's fast, and less if it's slow.

However, consider the converse too.  Is it possible that a site merely appears to be faster because users are using it more, and therefore have more of it cached?  I've seen sites where the server-side cache-hit ratio is much higher when usage is high resulting in lower latency.

At this point I haven't seen any data that can convince me one way or the other.  Do you?&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HHt8zKGDiI4:Q8OGzlWrEu0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HHt8zKGDiI4:Q8OGzlWrEu0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HHt8zKGDiI4:Q8OGzlWrEu0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HHt8zKGDiI4:Q8OGzlWrEu0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HHt8zKGDiI4:Q8OGzlWrEu0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/HHt8zKGDiI4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/7001500025860906590/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/12/a-correlation-between-load-time-and.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7001500025860906590?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7001500025860906590?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/HHt8zKGDiI4/a-correlation-between-load-time-and.html" title="A correlation between load time and usage" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/12/a-correlation-between-load-time-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AGRng8cSp7ImA9WhNSEk0.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-7195586286612360102</id><published>2012-10-25T14:48:00.000-07:00</published><updated>2012-10-25T14:48:47.679-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-25T14:48:47.679-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="startup" /><title>Startup Lessons: What should you optimise?</title><content type="html">&lt;p&gt;
In the early days, when you can't afford hardware, optimise for efficient code.
&lt;/p&gt;
&lt;p&gt;
Sometimes this results in unreadable code or a language that not too many developers are familiar with.  This is okay.  You're trying to reduce the cost of hardware.
&lt;/p&gt;

&lt;p&gt;
When you get large enough to hire other developers, the cost of hardware is no longer your largest expense.  At this point, optimise for code readability.
&lt;/p&gt;

&lt;p&gt;
This might mean writing slightly less efficient code or moving to a more popular language.  That's okay.  Developer efficiency is more important at this time.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=I63TrI7zcKE:oAdDDVCR_gY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=I63TrI7zcKE:oAdDDVCR_gY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=I63TrI7zcKE:oAdDDVCR_gY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=I63TrI7zcKE:oAdDDVCR_gY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=I63TrI7zcKE:oAdDDVCR_gY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/I63TrI7zcKE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/7195586286612360102/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/10/startup-lessons-what-should-you-optimise.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7195586286612360102?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7195586286612360102?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/I63TrI7zcKE/startup-lessons-what-should-you-optimise.html" title="Startup Lessons: What should you optimise?" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/10/startup-lessons-what-should-you-optimise.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04EQHk_eCp7ImA9WhJTGUk.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-4543273398155731472</id><published>2012-06-28T21:56:00.002-07:00</published><updated>2012-06-28T21:58:21.740-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-28T21:58:21.740-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ios" /><category scheme="http://www.blogger.com/atom/ns#" term="authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="two factor auth" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="wifi" /><title>iOS, Google WiFi and 2 factor auth -- clearly untested UX</title><content type="html">&lt;p&gt;
So after &lt;a href="http://www.webperfdays.org"&gt;WebPerfDays&lt;/a&gt; today, a bunch of us ended up at a Pizza place in Mountain View.  Naturally the first thing we all did was search for wifi in the area and try to get on to a network from our mobile devices.
&lt;/p&gt;
&lt;p&gt;
Now Mountain View has Google Wifi, and it appears as if they now require you to sign in with your Gmail account, and that's where the problem comes in... for me at least.  I have two factor auth turned on for my google accounts, which means that after I type in my username and password, I get to a second screen to enter my second authentication token.  This token comes from an app on my iOS device... the same device I was trying to log in with.
&lt;/p&gt;
&lt;p&gt;
I switched to the app to get the token number, but as soon as I did that, iOS decided that I didn't actually want to sign in to the wireless network, and disassociated itself from the Access Point (AP).
&lt;/p&gt;
&lt;p&gt;
Once I'd got the number, I switched back to the settings app and it initiated login again, which means I had to enter my username and password again, and by the time I'd reached the token screen, the token had expired.
&lt;/p&gt;
&lt;p&gt;
This is what the token screen looks like:
&lt;/p&gt;
&lt;div style="text-align: center;"&gt;&lt;img src="https://img.skitch.com/20120629-qgdjgqr985wq7sd66fxnfba5ah.png" href="iOS screenshot with Google 2 factor auth screen and Authenticator app"&gt;&lt;/div&gt;
&lt;p&gt;
It was rather annoying.
&lt;/p&gt;
&lt;p&gt;
It then hit me that I could copy the token to the clipboard, and then paste it into the token text field, which should shave a few seconds off and maybe let me through.
&lt;/p&gt;
&lt;p&gt;
That worked, but it was still annoying.
&lt;/p&gt;
&lt;p&gt;
We started talking about how this interface could be improved.  There are a few reasons why this is a problem, and I think they're mostly Apple's fault.
&lt;/p&gt;
&lt;p&gt;
When you connect to a wireless network, iOS attempts to connect to www.apple.com.  If it gets redirected somewhere else, it assumes that it's being asked to authenticate, and displays whatever page it gets redirected to in a browser like window.
&lt;/p&gt;
&lt;p&gt;
The problem is that if you do anything other than interact with the content in this window, iOS treats it exactly the same as hitting the "Cancel" button (top right of the screenshot), terminates the login and dissociates from the AP.
&lt;/p&gt;
&lt;p&gt;
This means that you cannot switch to the Authenticator App (second app at the bottom of the screenshot) to get your token.
&lt;/p&gt;
&lt;p&gt;
Can Apple fix this?
&lt;/p&gt;
&lt;p&gt;
Yes, just don't cancel sign in unless I explicitly click cancel
&lt;/p&gt;
&lt;p&gt;
Can Google fix this?
&lt;/p&gt;
&lt;p&gt;
Maybe, if they could provide a link or something that would open the Authenticator app right from that page and let me pull the number out of it (I don't know enough about iOS to know if this is possible).
&lt;/p&gt;
&lt;p&gt;
Do any Apple/Google engineers want to take this up?
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HKeRgeQaiFY:n3Dx54Crqrs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HKeRgeQaiFY:n3Dx54Crqrs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HKeRgeQaiFY:n3Dx54Crqrs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=HKeRgeQaiFY:n3Dx54Crqrs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=HKeRgeQaiFY:n3Dx54Crqrs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/HKeRgeQaiFY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/4543273398155731472/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/06/ios-google-wifi-and-2-factor-auth.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4543273398155731472?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4543273398155731472?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/HKeRgeQaiFY/ios-google-wifi-and-2-factor-auth.html" title="iOS, Google WiFi and 2 factor auth -- clearly untested UX" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/06/ios-google-wifi-and-2-factor-auth.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkANSH07fSp7ImA9WhVaEkQ.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-6012780358683396175</id><published>2012-06-09T11:17:00.002-07:00</published><updated>2012-06-09T19:19:59.305-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-09T19:19:59.305-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="passwords" /><category scheme="http://www.blogger.com/atom/ns#" term="groupon" /><category scheme="http://www.blogger.com/atom/ns#" term="ssl" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Password reset over HTTP -- Part 3</title><content type="html">&lt;p&gt;
It's been a while since my &lt;a href="http://tech.bluesmoon.info/2012/01/https-for-login-but-http-for-password.html"&gt;last&lt;/a&gt; &lt;a href="http://tech.bluesmoon.info/2012/01/password-reset-over-http-part-2.html"&gt;two&lt;/a&gt; posts on the topic.  This time it's Groupon.
&lt;/p&gt;

&lt;p&gt;
The password reset page is over HTTP:&lt;br&gt;
&lt;img src="https://img.skitch.com/20120609-q5p2x266t7kd7x362me6fig3sx.png" alt="groupon-forgot-password" /&gt;
&lt;/p&gt;

&lt;p&gt;
The reset password email that you receive contains a link that looks like this:
&lt;/p&gt;

&lt;pre&gt;
http://groupon.com/users/password_reset/{token}?utm_source=password_reset \
    &amp;utm_medium=email&amp;sid={sid}&amp;user={uid}&amp;date={YYYYmmdd}
&lt;/pre&gt;
&lt;p&gt;
This link does a 301 to itself and then a 302 to a HTTPS version of itself.
&lt;/p&gt;
&lt;p&gt;
The good thing is that your new password is sent over SSL.  The bad thing is that your reset token is sent in clear text.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt; This issue has been fixed by Groupon a couple of hours after reporting it.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=h5pTxjqruik:jrjRasaxM78:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=h5pTxjqruik:jrjRasaxM78:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=h5pTxjqruik:jrjRasaxM78:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=h5pTxjqruik:jrjRasaxM78:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=h5pTxjqruik:jrjRasaxM78:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/h5pTxjqruik" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/6012780358683396175/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/06/password-reset-over-http-part-3.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6012780358683396175?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6012780358683396175?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/h5pTxjqruik/password-reset-over-http-part-3.html" title="Password reset over HTTP -- Part 3" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/06/password-reset-over-http-part-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAMSX86cSp7ImA9WhRUF00.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-6902571639913344665</id><published>2012-01-27T14:36:00.000-08:00</published><updated>2012-01-27T14:36:28.119-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-27T14:36:28.119-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="form" /><category scheme="http://www.blogger.com/atom/ns#" term="pdf" /><category scheme="http://www.blogger.com/atom/ns#" term="printing" /><category scheme="http://www.blogger.com/atom/ns#" term="hack" /><category scheme="http://www.blogger.com/atom/ns#" term="macosx" /><title>Saving a PDF that doesn't allow saving form contents</title><content type="html">&lt;p&gt;Several organisations, consulates, for example, have forms that need to be filled up in PDFs.  They have very smart PDFs that change as you fill out the form and generate nice 2D bar codes at the end with all the information easily scannable when you submit the form.  Most of these forms can be saved after you've filled them out, which is important if it's complex and you need to work on it for a few days, or if you need to put it on a pen drive and take it somewhere else to print.&lt;/p&gt;
&lt;p&gt;
Every now and then however, I've come across a PDF that won't allow you to save the form contents.  This kinda sucks, so I decided to find a work around.
&lt;/p&gt;&lt;p&gt;
I first tried the print to PDF option, however Adobe won't let you print these particular PDFs to a PDF.
&lt;/p&gt;&lt;p&gt;
I tried Preview, but you can't fill out the form in Preview.
&lt;/p&gt;&lt;p&gt;
Then I tried actually printing it to a dummy printer.  Note that this is for MacOSX.

&lt;ol&gt;
&lt;li&gt;The first step is to open your printer settings.  If you don't have a printer create one:

&lt;div class="thumbnail"&gt;
&lt;a href="https://skitch.com/bluesmoon/ghtue/print-and-fax"&gt;&lt;img alt="Print &amp;amp; Fax" src="https://img.skitch.com/20120127-q7asqxmnd3jac5wmaargj8rnyx.preview.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;

&lt;li&gt;Then open the Print Queue and pause it
&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/ghtwe/hp-deskjet-f4200-series"&gt;&lt;img src="https://img.skitch.com/20120127-gtrgr7cxusp1pyxrwhynqudq1u.preview.jpg" alt="HP Deskjet F4200 series" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;

&lt;li&gt;Step 3, is to print your document to this printer.&lt;/li&gt;

&lt;li&gt;Now look into &lt;code&gt;/private/var/spool/cups&lt;/code&gt; for a file that was created within the last few minutes.  It should start with &lt;code&gt;d&lt;/code&gt; and have a lot of numbers after it. You'll need sudo:
&lt;pre&gt;sudo ls -l /private/var/spool/cups&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;copy this file somewhere convenient, and give it a &lt;code&gt;.ps&lt;/code&gt; extension (it's a postscript file).&lt;/li&gt;

&lt;li&gt;You can now open this file with Preview.  I recommend opening it and reordering the pages, and then save it as a PDF.&lt;/li&gt;
&lt;/ol&gt;

That's it.

There's a way to do it for windows too, but I don't have a windows box handy to document it.  Linux is trivial.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=D4jlz92yTag:CAL9khtlOB0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=D4jlz92yTag:CAL9khtlOB0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=D4jlz92yTag:CAL9khtlOB0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=D4jlz92yTag:CAL9khtlOB0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=D4jlz92yTag:CAL9khtlOB0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/D4jlz92yTag" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/6902571639913344665/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/01/saving-pdf-that-doesnt-allow-saving.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6902571639913344665?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6902571639913344665?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/D4jlz92yTag/saving-pdf-that-doesnt-allow-saving.html" title="Saving a PDF that doesn't allow saving form contents" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/01/saving-pdf-that-doesnt-allow-saving.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYBRngzcCp7ImA9WhRUFUw.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-8460544245142580307</id><published>2012-01-25T09:21:00.000-08:00</published><updated>2012-01-25T09:22:37.688-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T09:22:37.688-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="http" /><category scheme="http://www.blogger.com/atom/ns#" term="passwords" /><category scheme="http://www.blogger.com/atom/ns#" term="ssl" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Password reset over HTTP -- Part 2</title><content type="html">&lt;p&gt;
So it looks like I've been forgetting a lot of my passwords recently.  After yesterday's issue with &lt;a href="http://tech.bluesmoon.info/2012/01/https-for-login-but-http-for-password.html"&gt;delicious submitting passwords in the clear&lt;/a&gt;, today I have a problem with livemocha.com.
&lt;/p&gt;&lt;p&gt;
As before, their login page is properly secured, but the password reset page is over HTTP:
&lt;/p&gt;&lt;p&gt;
This is the password reset page:
&lt;/p&gt;
&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g52th/livemocha-password-reset-over-http"&gt;&lt;img src="https://img.skitch.com/20120125-g2u5ngmj819qbc6hdg7i9khk96.preview.jpg" alt="livemocha - password reset over http" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;
And this is the URL the passwords are POSTed to, in clear text:
&lt;/p&gt;
&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g52ug/livemocha-password-reset-submitted-over-http"&gt;&lt;img src="https://img.skitch.com/20120125-xwubw8hy8484ngbhy3xewq56k.preview.jpg" alt="livemocha - password reset submitted over http" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;
They also include third party code on their page, in this case it's a flash object from userplane.com, google analytics, and some JavaScript from pbc.com (alias for paybycash.com)
&lt;/p&gt;&lt;p&gt;
I've gotten in touch with them via their online form.  Let's hope they respond.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=646zXucOHIw:w6OR8TP9dis:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=646zXucOHIw:w6OR8TP9dis:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=646zXucOHIw:w6OR8TP9dis:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=646zXucOHIw:w6OR8TP9dis:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=646zXucOHIw:w6OR8TP9dis:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/646zXucOHIw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/8460544245142580307/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/01/password-reset-over-http-part-2.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/8460544245142580307?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/8460544245142580307?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/646zXucOHIw/password-reset-over-http-part-2.html" title="Password reset over HTTP -- Part 2" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/01/password-reset-over-http-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANQHc7eCp7ImA9WhRUFU8.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-4792489621585390972</id><published>2012-01-24T13:58:00.000-08:00</published><updated>2012-01-25T13:09:51.900-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T13:09:51.900-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="http" /><category scheme="http://www.blogger.com/atom/ns#" term="passwords" /><category scheme="http://www.blogger.com/atom/ns#" term="ssl" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>HTTPS for login but HTTP for password resets</title><content type="html">I recently tried to log in to my delicious.com account, and realised that I'd forgotten my password, so went through the reset password flow.  This is what I saw...

&lt;ol&gt;
&lt;li&gt;The Sign-in page is over SSL, which is good:

&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g5x6n/delicious-login-over-ssl"&gt;&lt;img src="https://img.skitch.com/20120124-jcgci9q4guipyibr14hkhtepk6.preview.jpg" alt="delicious login over ssl" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li&gt;The Forgot password page, where you enter your username is also over HTTPS.  Not strictly required, but good all the same:

&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g5x9q/delicious-forgot-password-over-https"&gt;&lt;img src="https://img.skitch.com/20120124-qebkmsijrxtakkbqmwetgb3rw5.preview.jpg" alt="delicious - forgot password over HTTPS" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li&gt;This sends you an email with a link to reset your password.  This page is not over HTTPS:

&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g5tbq/delicious-reset-password-page-not-over-https"&gt;&lt;img src="https://img.skitch.com/20120124-qmnkpq1gjk9mtafdd2ba327aww.preview.jpg" alt="delicious - reset password page -- not over HTTPS" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li&gt;And submitting this form also goes to a page that is not over HTTPS:

&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/bluesmoon/g5tfp/delicious-form-submit-over-http"&gt;&lt;img src="https://img.skitch.com/20120124-njc2j1i3x937xunmqx11b4c9m6.preview.jpg" alt="delicious -- form submit over http" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Now they put the login page on HTTPS, which shows that they want to protect the user's password from sniffing, but the password reset form, which also accepts the user's password, sends the password in clear text over HTTP.  This isn't good.  If you're going to protect passwords via SSL, do it everywhere.  FWIW, the userid (but not the username) is also sent in this form.
&lt;/p&gt;
&lt;p&gt;
Additionally, the password reset page contains JavaScript from google analytics and chartbeat.  As I've written before, you &lt;a href="http://tech.bluesmoon.info/2011/04/how-much-do-you-trust-third-party.html"&gt;shouldn't trust third party scripts&lt;/a&gt;.  While you may choose to ignore this on most pages, pages that accept the user's credentials should be considered sacred.  The user assumes that anything they enter on this page is available only to your servers.  By including third party JavaScript, you're breaking that trust.
&lt;/p&gt;
&lt;p&gt;
I've emailed violations@delicious.com with these details, and am awaiting a response.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Update 2012-01-25 21:08 UTC:&lt;/strong&gt; As of this time, Delicious have fixed the core issue of the password reset page being on HTTP.  Kudos to the team for acting quickly.  The secondary issue of third party scripts on this page still remains, but that's a policy decision for them, and not me.
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=_MA_DV0o8lM:_hG9XS0nw8A:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=_MA_DV0o8lM:_hG9XS0nw8A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=_MA_DV0o8lM:_hG9XS0nw8A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=_MA_DV0o8lM:_hG9XS0nw8A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=_MA_DV0o8lM:_hG9XS0nw8A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/_MA_DV0o8lM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/4792489621585390972/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2012/01/https-for-login-but-http-for-password.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4792489621585390972?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4792489621585390972?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/_MA_DV0o8lM/https-for-login-but-http-for-password.html" title="HTTPS for login but HTTP for password resets" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2012/01/https-for-login-but-http-for-password.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFQno5fSp7ImA9WhRQFUU.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-6584135459762075648</id><published>2011-12-10T22:58:00.001-08:00</published><updated>2011-12-10T23:06:53.425-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-10T23:06:53.425-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="http" /><category scheme="http://www.blogger.com/atom/ns#" term="curl" /><category scheme="http://www.blogger.com/atom/ns#" term="unix" /><category scheme="http://www.blogger.com/atom/ns#" term="ipv6" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><title>Using curl with IPv6 addresses</title><content type="html">Assuming you have a curl compiled with IPv6, if you wanted to hit a page using its IPv6 address rather than its hostname, you have to do it as follows:
&lt;pre&gt;
curl "http://\[2600:xxx:yyy::zzz\]/page.html"
&lt;/pre&gt;
The square brackets are required to tell curl that it's an IPv6 address and not a host:port pair.

The quotes are required to stop the shell from treating the square brackets as a glob.

The backslash is required to stop curl from treating the square brackets as a range specification.

The &lt;code&gt;http://&lt;/code&gt; is optional, but good form.

This isn't required if you use a hostname or an IPv4 address.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=hUHmgokIGic:3lNbGEtTH3U:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=hUHmgokIGic:3lNbGEtTH3U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=hUHmgokIGic:3lNbGEtTH3U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=hUHmgokIGic:3lNbGEtTH3U:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=hUHmgokIGic:3lNbGEtTH3U:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/hUHmgokIGic" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/6584135459762075648/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/12/using-curl-with-ipv6-addresses.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6584135459762075648?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/6584135459762075648?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/hUHmgokIGic/using-curl-with-ipv6-addresses.html" title="Using curl with IPv6 addresses" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/12/using-curl-with-ipv6-addresses.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4MSX08fSp7ImA9WhRQFUU.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-3029095636472811239</id><published>2011-12-04T21:59:00.001-08:00</published><updated>2011-12-10T23:03:08.375-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-10T23:03:08.375-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wav" /><category scheme="http://www.blogger.com/atom/ns#" term="mp3" /><category scheme="http://www.blogger.com/atom/ns#" term="unix" /><category scheme="http://www.blogger.com/atom/ns#" term="audio" /><title>Converting mp3s to wavs with mplayer</title><content type="html">Yesterday I had to convert a few mp3 files to wavs.  I also needed to crop them a bit on both ends.  This is how I did it:
&lt;pre&gt;
mplayer -ss 0.5 -endpos 1:14 -ao pcm:file="newfile.wav" oldfile.mp3
&lt;/pre&gt;
This is how it works:
&lt;code&gt;-ss&lt;/code&gt; says how many seconds of the file to skip at the start.  If you don't know the time, but the number of bytes instead, use &lt;code&gt;-sb&lt;/code&gt; instead.  Note that &lt;code&gt;-ss&lt;/code&gt; only works with seconds, but accepts fractional seconds.

&lt;code&gt;-endpos&lt;/code&gt; says at what point to stop playing.  This accepts time as &lt;code&gt;hh:mm:ss.ms&lt;/code&gt; or in bytes.  If you specify only one number, it's seconds.

&lt;code&gt;-ao&lt;/code&gt; is a special instruction that specifies a plugin, and everything following the plugin are plugin specific options.  &lt;code&gt;pcm&lt;/code&gt; is the format for wave files.  You could use any format you like.  &lt;code&gt;mplayer -ao help&lt;/code&gt; will tell you which codecs are supported.  I haven't figured out all the suboptions for &lt;code&gt;pcm&lt;/code&gt; yet.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=fX7BNFtf_Vg:XXTk7RTtzR0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=fX7BNFtf_Vg:XXTk7RTtzR0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=fX7BNFtf_Vg:XXTk7RTtzR0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=fX7BNFtf_Vg:XXTk7RTtzR0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=fX7BNFtf_Vg:XXTk7RTtzR0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/fX7BNFtf_Vg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/3029095636472811239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/12/converting-mp3s-to-wavs-with-mplayer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3029095636472811239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3029095636472811239?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/fX7BNFtf_Vg/converting-mp3s-to-wavs-with-mplayer.html" title="Converting mp3s to wavs with mplayer" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/12/converting-mp3s-to-wavs-with-mplayer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEENRH09eSp7ImA9WhdWE0s.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-3639580975144506520</id><published>2011-09-06T15:19:00.000-07:00</published><updated>2011-09-06T20:38:15.361-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-06T20:38:15.361-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="ephemeral ports" /><category scheme="http://www.blogger.com/atom/ns#" term="network" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="load" /><title>The Limits of Network Load Testing – Ephemeral Ports</title><content type="html">&lt;p&gt;I've been trying to run load tests against a &lt;code&gt;node.js&lt;/code&gt; web app that I'm working on.  I've hacked up my app to log (every 5 seconds) the number of requests per second that it handles and the amount of memory that it uses.  I saw some strange numbers.  I should also mention that I was using &lt;code&gt;ab&lt;/code&gt; to throw load at the server.  Perhaps not the best load tester around, but it served my purpose for this particular test.
&lt;/p&gt;&lt;p&gt;
My app started out well, handling about 1500 requests per second, but then all of a sudden it would stop serving requests.  With repeated runs, the point where it would stop was always around 16K connections... in fact, it always hovered around 16384, mostly staying below, but sometimes going above it a bit (eg: 16400).
&lt;/p&gt;
&lt;h4&gt;Ephemeral Ports&lt;/h4&gt;
&lt;p&gt;
To those of you familiar with TCP networking, you'll recognise that value as the &lt;abbr title="Internet Assigned Numbers Authority"&gt;IANA&lt;/abbr&gt; specified number of &lt;a href="http://en.wikipedia.org/wiki/Ephemeral_port"&gt;Ephemeral Ports&lt;/a&gt; (49152 to 65535).
&lt;/p&gt;&lt;p&gt;
I started to log the state of all TCP connections every second using the following shell script (split onto multiple lines for readability):
&lt;/p&gt;
&lt;pre&gt;while true; do
   echo -n "$( date +%s ) ";
   netstat | \
      awk '$4~/\.http-alt/ { conn[$6]++ }
           END {
              for(c in conn) {
                 printf("%s: %d\t", c, conn[c]);
              } 
              printf("\n");
           }
      ';
   sleep 1;
done
&lt;/pre&gt;
This is the output it returned:
&lt;pre&gt;
1315341300 TIME_WAIT: 209	ESTABLISHED: 100	
1315341301 FIN_WAIT_1: 4	FIN_WAIT_2: 4	TIME_WAIT: 1892	ESTABLISHED: 92	
1315341302 FIN_WAIT_1: 1	FIN_WAIT_2: 2	TIME_WAIT: 3725	ESTABLISHED: 97	
1315341303 FIN_WAIT_2: 2	TIME_WAIT: 5426	ESTABLISHED: 97	
1315341304 FIN_WAIT_1: 1	FIN_WAIT_2: 5	TIME_WAIT: 7017	ESTABLISHED: 94	
1315341305 TIME_WAIT: 8722	ESTABLISHED: 100	
1315341306 FIN_WAIT_1: 2	TIME_WAIT: 10459	ESTABLISHED: 98	
1315341308 FIN_WAIT_1: 3	FIN_WAIT_2: 3	TIME_WAIT: 12246	ESTABLISHED: 94	
1315341309 FIN_WAIT_1: 7	TIME_WAIT: 14031	ESTABLISHED: 93	
1315341310 FIN_WAIT_1: 3	TIME_WAIT: 15937	ESTABLISHED: 97	
1315341311 TIME_WAIT: 16363	
1315341312 TIME_WAIT: 16363	
1315341314 TIME_WAIT: 16363	
1315341315 TIME_WAIT: 16363	
1315341316 TIME_WAIT: 16363	
1315341317 TIME_WAIT: 16363	
1315341318 TIME_WAIT: 16363	
1315341319 TIME_WAIT: 16363	
1315341321 TIME_WAIT: 16363	
1315341322 TIME_WAIT: 16363	
1315341323 TIME_WAIT: 16363	
1315341324 TIME_WAIT: 16363	
1315341325 TIME_WAIT: 16363	
1315341326 TIME_WAIT: 16363	
1315341328 TIME_WAIT: 16363	
1315341329 TIME_WAIT: 16363	
1315341330 TIME_WAIT: 16363	
1315341331 TIME_WAIT: 14321	
1315341332 TIME_WAIT: 12641	
1315341333 TIME_WAIT: 11024	
1315341334 TIME_WAIT: 9621	
1315341336 TIME_WAIT: 7516	
1315341337 TIME_WAIT: 5920	
1315341338 TIME_WAIT: 4227	
1315341339 TIME_WAIT: 2693	
1315341340 TIME_WAIT: 1108	
1315341341 TIME_WAIT: 23&lt;/pre&gt;
There are a few things to note here.
&lt;ol&gt;
&lt;li&gt;I ran &lt;code&gt;ab&lt;/code&gt; with concurrency set to 100, so the number of connections in the &lt;code&gt;ESTABLISHED&lt;/code&gt;, and &lt;code&gt;FIN_WAIT_{1,2}&lt;/code&gt; states should be about 100 for the most part&lt;/li&gt;
&lt;li&gt;I was polling netstat once per second + the amount of time it took netstat to return, so you might notice missing seconds in between&lt;/li&gt;
&lt;li&gt;Requests were being handled at over 1000 per second, so many of the connections would have gone from the &lt;code&gt;SYN_SENT&lt;/code&gt; state to &lt;code&gt;TIME_WAIT&lt;/code&gt; in less than 1 second.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
It's pretty clear here that everything just stops once the number of connections reaches 16363, and my app's logs confirm that.  &lt;code&gt;ab&lt;/code&gt; ends up timing out somewhere near the end of this report (which should probably be the subject of a different blog post).
&lt;/p&gt;
&lt;p&gt;
Now if we look closely, we notice that it takes 30 seconds from the first result we see to when the number of connections in the &lt;code&gt;TIME_WAIT&lt;/code&gt; state start dropping below 16363
&lt;/p&gt;
&lt;h4&gt;TIME_WAIT&lt;/h4&gt;
A few points should be noted about the TIME_WAIT state.
&lt;ol&gt;
&lt;li&gt;Only the endpoint that sends the first &lt;code&gt;FIN&lt;/code&gt; will end up in a TIME_WAIT state.  I'll tell you later why this is important&lt;/li&gt;
&lt;li&gt;A connection remains in the &lt;code&gt;TIME_WAIT&lt;/code&gt; state for twice the connection's &lt;abbr title="Maximum Segment Lifetime"&gt;MSL&lt;/abbr&gt; (See &lt;a href="http://www.rfc-editor.org/rfc/rfc793.txt"&gt;RFC793&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
So we now have a whole load of TCP connections in the TIME_WAIT state and the client (the load tester) has run out of ephemeral ports to keep running the test.  This is independent of the load tester used, and how it handles its sockets (poll, select, multiple threads, multiple processes, whatever).  This is a limit imposed by the Operating System in order to comply with the TCP spec, and in general make sure the internet doesn't break.
&lt;/p&gt;
&lt;p&gt;
Now there are various ways to get around this limit.  The simplest is to just use multiple boxes to run your performance test all simultaneously hitting your server.  The more boxes you use, the more likely it is that your server will break down before your client hits the port limit.  But what if you don't have access to so many boxes (in a world without EC2 for example), or it's too expensive, or you're not utilising the other resources (CPU/RAM/Network Interface) on your client boxes and would like to get a little more out of them?
&lt;/p&gt;
&lt;p&gt;
You could program your load tester to use &lt;code&gt;SO_REUSEADDR&lt;/code&gt;, which would allow it to reuse sockets that are in the TIME_WAIT state, but that could backfire if there's still data on the network.
&lt;/p&gt;

&lt;h4&gt;MSL&lt;/h4&gt;
&lt;p&gt;
Now remember that TIME_WAIT is twice the MSL.  RFC793 recommends setting the MSL to 2 minutes, which would leave TIME_WAIT at 4 minutes.  Luckily no current implementation uses this value.  Linux has its TIME_WAIT length &lt;a href="https://github.com/torvalds/linux/blob/master/include/net/tcp.h#L106"&gt;hardcoded to 60 seconds&lt;/a&gt; (implying a 30 second MSL), while BSD has set to 15 seconds (&lt;code&gt;sysctl net.inet.tcp.msl&lt;/code&gt;) and tunable at run time.
&lt;/p&gt;
&lt;p&gt;
To verify, I reran the test after setting the MSL to 5 seconds:
&lt;/p&gt;
&lt;pre&gt;
sudo sysctl -w net.inet.tcp.msl=5000
&lt;/pre&gt;
&lt;p&gt;
And these were the results:
&lt;/p&gt;
&lt;pre&gt;
1315344661 TIME_WAIT: 1451	ESTABLISHED: 100	
1315344662 FIN_WAIT_2: 5	TIME_WAIT: 3272	ESTABLISHED: 95	
1315344664 FIN_WAIT_1: 1	TIME_WAIT: 5010	ESTABLISHED: 99	
1315344665 TIME_WAIT: 6574	ESTABLISHED: 100	
1315344666 FIN_WAIT_1: 11	FIN_WAIT_2: 2	TIME_WAIT: 7908	ESTABLISHED: 87	
1315344667 TIME_WAIT: 9689	ESTABLISHED: 100	
1315344668 TIME_WAIT: 11155	ESTABLISHED: 100	
1315344669 FIN_WAIT_1: 3	TIME_WAIT: 12522	ESTABLISHED: 97	
1315344671 FIN_WAIT_2: 2	TIME_WAIT: 13655	ESTABLISHED: 98	
1315344672 FIN_WAIT_1: 4	FIN_WAIT_2: 12	TIME_WAIT: 13847	ESTABLISHED: 84	
1315344673 FIN_WAIT_1: 2	TIME_WAIT: 13218	ESTABLISHED: 98	
1315344674 FIN_WAIT_1: 2	TIME_WAIT: 13723	ESTABLISHED: 97	
1315344675 FIN_WAIT_1: 2	TIME_WAIT: 14441	ESTABLISHED: 98	
1315344677 FIN_WAIT_1: 4	FIN_WAIT_2: 6	TIME_WAIT: 13946	ESTABLISHED: 90	
1315344678 FIN_WAIT_1: 3	FIN_WAIT_2: 15	TIME_WAIT: 14670	ESTABLISHED: 82	
1315344679 FIN_WAIT_1: 2	TIME_WAIT: 15164	ESTABLISHED: 98	
1315344680 FIN_WAIT_1: 2	TIME_WAIT: 15062	ESTABLISHED: 98	
1315344681 TIME_WAIT: 15822	ESTABLISHED: 100	
1315344683 FIN_WAIT_1: 4	TIME_WAIT: 15855	ESTABLISHED: 82	
1315344684 FIN_WAIT_1: 15	TIME_WAIT: 15506	ESTABLISHED: 84	
1315344685 FIN_WAIT_2: 9	TIME_WAIT: 15928	ESTABLISHED: 91	
1315344687 FIN_WAIT_1: 4	TIME_WAIT: 15356	ESTABLISHED: 96	
1315344688 FIN_WAIT_1: 2	FIN_WAIT_2: 8	TIME_WAIT: 15490	ESTABLISHED: 90	
1315344689 FIN_WAIT_1: 1	TIME_WAIT: 15449	ESTABLISHED: 99	
1315344690 FIN_WAIT_1: 3	TIME_WAIT: 15801	ESTABLISHED: 97	
1315344692 FIN_WAIT_1: 1	TIME_WAIT: 15882	ESTABLISHED: 70	
1315344693 FIN_WAIT_1: 3	TIME_WAIT: 16106	ESTABLISHED: 56	
1315344694 FIN_WAIT_1: 3	TIME_WAIT: 15637	ESTABLISHED: 2	
1315344695 TIME_WAIT: 14166	
1315344697 TIME_WAIT: 12588	
1315344698 TIME_WAIT: 10454	
1315344699 TIME_WAIT: 8917	
1315344700 TIME_WAIT: 7441	
1315344701 TIME_WAIT: 5735	
1315344702 TIME_WAIT: 4119	
1315344703 TIME_WAIT: 1815	
1315344704 TIME_WAIT: 88	
&lt;/pre&gt;
&lt;p&gt;
The test runs longer here because it actually gets to 50000 connections.  We're doing about 1500 requests per second, so it would take just under 11 seconds to exhaust all 16384 ports, but since ports are reusable in 10 seconds, we would have reclaimed the first 3000 ports in this time and then just continue to use them.
&lt;/p&gt;
&lt;p&gt;
Here's the catch though, you can only do this on BSD.  Linux doesn't let you change the MSL.  Also, DO NOT DO THIS IN PRODUCTION!
&lt;/p&gt;
&lt;h4&gt;TIME_WAIT, FIN and HTTP keep-alive&lt;/h4&gt;
&lt;p&gt;
Now I mentioned earlier that only the endpoint that sends the first FIN packet will enter the TIME_WAIT state.  This is important because in production, you really do not want your server to end up with a lot of connections in the TIME_WAIT state.  A malicious user could, for example, make a large number of HEAD requests to your server, and either wait for them to terminate, or specify &lt;code&gt;Connection:close&lt;/code&gt; but leave the connection open for your server to close by sending the first FIN packet.
&lt;/p&gt;
&lt;p&gt;
How do you deal with this?
&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=WGNLZAMqXqo:uLrnJ_rN4wM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=WGNLZAMqXqo:uLrnJ_rN4wM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=WGNLZAMqXqo:uLrnJ_rN4wM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=WGNLZAMqXqo:uLrnJ_rN4wM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=WGNLZAMqXqo:uLrnJ_rN4wM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/WGNLZAMqXqo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/3639580975144506520/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/09/limits-of-network-load-testing-ports.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3639580975144506520?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3639580975144506520?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/WGNLZAMqXqo/limits-of-network-load-testing-ports.html" title="The Limits of Network Load Testing &amp;ndash; Ephemeral Ports" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/09/limits-of-network-load-testing-ports.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkABQ3s6eCp7ImA9WhdTFko.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-1275165773514694849</id><published>2011-07-14T12:12:00.000-07:00</published><updated>2011-07-14T12:12:32.510-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-14T12:12:32.510-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="API" /><category scheme="http://www.blogger.com/atom/ns#" term="couchdb" /><category scheme="http://www.blogger.com/atom/ns#" term="nodejs" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>CouchDB drivers for NodeJS</title><content type="html">I've been looking at writing some code in &lt;a href="http://nodejs.org/"&gt;NodeJS&lt;/a&gt;, and wanted to use &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; as the data store (note, I don't have relational data).  I've come across the following libraries, all coincidentally on &lt;a href="http://github.com/"&gt;github&lt;/a&gt;.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;couch-client&lt;/li&gt;
&lt;li&gt;cradle&lt;/li&gt;
&lt;li&gt;noddycouch&lt;/li&gt;
&lt;li&gt;node-couch&lt;/li&gt;
&lt;li&gt;node-couchdb&lt;/li&gt;
&lt;li&gt;node-couchdb-min&lt;/li&gt;
&lt;/ul&gt;At this point I've only looked at the documentation, so I don't have a detailed idea of which I'd use.  If you have your own favourites, please mention them in the comments.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/creationix/couch-client"&gt;couch-client&lt;/a&gt;&lt;/h4&gt;The documentation seems reasonably rich, and it has all the methods that I'd like to use.  My only concern at this point is that it batches up writes.  This may not be ideal for my particular use case, but it isn't a show stopper.&lt;br /&gt;
&lt;br /&gt;
There are no installation/setup docs, so I assume I've got to clone the github repo to get it.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/cloudhead/cradle"&gt;cradle&lt;/a&gt;&lt;/h4&gt;I've been impressed with cradle's docs so far, and it's also available through &lt;code&gt;npm&lt;/code&gt;, which is a plus.  It also distinguishes between creating a document with and without an id, which may be required in my use case.&lt;br /&gt;
&lt;br /&gt;
Lastly, cradle mentions an SSL use case, which I think is important.  The other libraries may also have SSL support, but they don't explicitly call it out.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/benoitc/noddycouch"&gt;noddycouch&lt;/a&gt;&lt;/h4&gt;No docs available, but example.js has code examples on how to use it.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/sixtus/node-couch"&gt;node-couch&lt;/a&gt;&lt;/h4&gt;Again, no docs available, except to say that it was inspired by the jQuery module for NodeJS.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/felixge/node-couchdb"&gt;node-couchdb&lt;/a&gt;&lt;/h4&gt;Very good documentation and seems to be a very thorough API, but the owner says he isn't maintaining the package any more.  That's a big downside.&lt;br /&gt;
&lt;h4&gt;&lt;a href="https://github.com/rsms/node-couchdb-min"&gt;node-couchdb-min&lt;/a&gt;&lt;/h4&gt;This appears to be a minimal version of node-couchdb.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=kaQn4x0-nXE:xXPPMTtfRQg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=kaQn4x0-nXE:xXPPMTtfRQg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=kaQn4x0-nXE:xXPPMTtfRQg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=kaQn4x0-nXE:xXPPMTtfRQg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=kaQn4x0-nXE:xXPPMTtfRQg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/kaQn4x0-nXE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/1275165773514694849/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/07/couchdb-drivers-for-nodejs.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1275165773514694849?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1275165773514694849?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/kaQn4x0-nXE/couchdb-drivers-for-nodejs.html" title="CouchDB drivers for NodeJS" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/07/couchdb-drivers-for-nodejs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYFRH4zcCp7ImA9WhZbE04.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-2393319035518067621</id><published>2011-06-17T11:01:00.000-07:00</published><updated>2011-06-17T11:08:35.088-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-17T11:08:35.088-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="prerender" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="ipv6" /><category scheme="http://www.blogger.com/atom/ns#" term="webtiming" /><category scheme="http://www.blogger.com/atom/ns#" term="boomerang" /><title>NavigationTiming, IPv6, Instant Pages and other goodies in boomerang</title><content type="html">There have been many additions to &lt;a href="http://yahoo.github.com/boomerang/doc/"&gt;boomerang&lt;/a&gt; over the last few months.  Among them include:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Full navigation timing API support added by &lt;a href="http://buddybrewer.com/"&gt;Buddy Brewer&lt;/a&gt; (&lt;a href="https://twitter.com/bbrewer"&gt;@bbrewer&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Measure IPv6 support and latency with the ipv6 plugin&lt;/li&gt;
&lt;li&gt;Measure the performance of "Instant Pages" in Google Chrome (v13+)&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;NavigationTiming&lt;/h4&gt;With the &lt;code&gt;navtiming.js&lt;/code&gt; plugin, boomerang will beacon back the entire navigation timing object for browsers that support it (Chrome 6+ and IE 9+ and Firefox 6+ at this time).  Use this information to gain far more insight into the user's browsing experience.&lt;br /&gt;
&lt;br /&gt;
Docs here: &lt;a href="http://yahoo.github.com/boomerang/doc/api/navtiming.html"&gt;http://yahoo.github.com/boomerang/doc/api/navtiming.html&lt;/a&gt; and here: &lt;a href="http://yahoo.github.com/boomerang/doc/howtos/howto-9.html"&gt;http://yahoo.github.com/boomerang/doc/howtos/howto-9.html&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;IPv6&lt;/h4&gt;World IPv6 day is past, but IPv6 support still isn't universal.  The &lt;code&gt;ipv6.js&lt;/code&gt; plugin will help you find out if your users can access content&amp;nbsp;over IPv6 and how that latency compares to whatever you currently provide.  This does require server side setup though.&lt;br /&gt;
&lt;br /&gt;
Docs here: &lt;a href="http://yahoo.github.com/boomerang/doc/api/ipv6.html"&gt;http://yahoo.github.com/boomerang/doc/api/ipv6.html&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;Instant Pages&lt;/h4&gt;Google Chrome 13 has taken Mozilla's &lt;a href="https://developer.mozilla.org/en/Link_prefetching_FAQ"&gt;prefetch&lt;/a&gt; technology to the next&amp;nbsp;level, introducing "&lt;a href="http://code.google.com/chrome/whitepapers/prerender.html"&gt;prerender&lt;/a&gt;" -- a method to download and render the most likely next page before the user clicks on it, giving the appearance of the page loading Instantly when the user does click.&lt;br /&gt;
&lt;br /&gt;
Boomerang is now prerender aware, and will check to see if a page was&amp;nbsp;loaded through prerender or not.  If it was, then boomerang measures a few more interesting times like the actual load time, the perceived load&amp;nbsp;time, and the time from prerender completing to the page becoming visible.&lt;br /&gt;
&lt;br /&gt;
Caveat: The measurement code &lt;a href="http://code.google.com/p/chromium/issues/detail?id=86310"&gt;causes current builds of Chrome 13 to crash&lt;/a&gt;.  This bug appears to have been fixed in the nightlies (Chrome 14 Canary).&lt;br /&gt;
&lt;br /&gt;
Docs here: &lt;a href="http://yahoo.github.com/boomerang/doc/howtos/howto-10-page%231.html"&gt;http://yahoo.github.com/boomerang/doc/howtos/howto-10-page%231.html&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=SaJKN3SWpl8:aLadeGGKOno:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=SaJKN3SWpl8:aLadeGGKOno:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=SaJKN3SWpl8:aLadeGGKOno:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=SaJKN3SWpl8:aLadeGGKOno:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=SaJKN3SWpl8:aLadeGGKOno:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/SaJKN3SWpl8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/2393319035518067621/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/06/navigationtiming-ipv6-instant-pages-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2393319035518067621?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2393319035518067621?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/SaJKN3SWpl8/navigationtiming-ipv6-instant-pages-and.html" title="NavigationTiming, IPv6, Instant Pages and other goodies in boomerang" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/06/navigationtiming-ipv6-instant-pages-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UBQH4-eCp7ImA9WhZUEUs.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-4985970490707695113</id><published>2011-06-03T23:33:00.000-07:00</published><updated>2011-06-03T23:34:11.050-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-03T23:34:11.050-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="xss" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Almost right is not right enough</title><content type="html">I was recently pointed to &lt;a href="http://scrumy.com/"&gt;scrumy.com&lt;/a&gt; by a group that wants to use the scrum agile method.  A quick look around the site showed that they were doing a lot in JavaScript.  In particular, they took the name of the current scrum (or sprint if you prefer) from the URL and wrote it into the HTML, JavaScript and a few URLs.  So, if your sprint were named &lt;code&gt;hello-dolly&lt;/code&gt;, your URL would be &lt;code&gt;http://scrumy.com/hello-dolly/&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Here's the sad part... they &lt;em&gt;almost&lt;/em&gt; got their filtering right.  When written into the HTML, they correctly encoded used HTML entities and when written into URLs, they correctly URI encoded the data.  They even did this for URIs that were written into JavaScript variables.&lt;br /&gt;
&lt;br /&gt;
Where they didn't encode, was a JavaScript variable not used in any of these contexts.  A small part of their JavaScript for the hello-dolly example reads like this:&lt;br /&gt;
&lt;pre&gt;window.projectName="hello-dolly";
&lt;/pre&gt;Change the URL to &lt;code&gt;http://scrumy.com/%22%3balert(0)%3b%22&lt;/code&gt; and this is what gets written into the page:&lt;br /&gt;
&lt;pre&gt;window.projectName="";alert(0);"";
&lt;/pre&gt;Resulting in an XSS.&lt;br /&gt;
&lt;br /&gt;
Now I only looked at a single page on the site, so can't comment on whether there are more holes or not.&lt;br /&gt;
&lt;br /&gt;
I emailed them as soon as I found the bug and a few hours later it was fixed.  Good job folks!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=IYeVe3zq6oc:pEVmRkTGnkg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=IYeVe3zq6oc:pEVmRkTGnkg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=IYeVe3zq6oc:pEVmRkTGnkg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=IYeVe3zq6oc:pEVmRkTGnkg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=IYeVe3zq6oc:pEVmRkTGnkg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/IYeVe3zq6oc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/4985970490707695113/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/06/almost-right-is-not-right-enough.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4985970490707695113?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/4985970490707695113?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/IYeVe3zq6oc/almost-right-is-not-right-enough.html" title="Almost right is not right enough" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/06/almost-right-is-not-right-enough.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQFRXszcCp7ImA9WhZXFUU.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-192574653044358069</id><published>2011-05-05T02:35:00.000-07:00</published><updated>2011-05-05T02:38:34.588-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-05T02:38:34.588-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="george" /><category scheme="http://www.blogger.com/atom/ns#" term="developer" /><category scheme="http://www.blogger.com/atom/ns#" term="ayttm" /><category scheme="http://www.blogger.com/atom/ns#" term="opensource" /><title>The story of George — ayttm's most prolific non-developing contributor</title><content type="html">&lt;h4&gt;An Introduction&lt;/h4&gt;In late April 2008, we received an email&lt;sup&gt;[&lt;a href="#bm-george-email"&gt;1&lt;/a&gt;]&lt;/sup&gt; on the ayttm-users mailing list.  It was from George, which wasn't a name I'd ever seen on the list before, and it was about something called Puppy Linux&lt;sup&gt;[&lt;a href="#bm-puppy"&gt;2&lt;/a&gt;]&lt;/sup&gt;, a distribution I'd never heard of before.  He started out with a description of the distro, stating that he was a user, and had picked up ayttm&lt;sup&gt;[&lt;a href="#bm-ayttm"&gt;3&lt;/a&gt;]&lt;/sup&gt; based on the suggestion of the creator of Puppy Linux on their chatroom.&lt;br /&gt;
&lt;br /&gt;
As part of his introduction, he included this paragraph:&lt;br /&gt;
&lt;blockquote&gt;I am very new to all this. Although I was a programmer years ago, I was away from computers for about 20 years. I have been on the internet for about 14 months - with no previous internet experience. I got Puppy Linux up and running less than 6 months ago - no previous linux / unix experience. I've been using chat rooms about two months - again with no previous experience. I only use irc.FreeNode.net and I access almost exclusively the Puppy Linux chat rooms.&lt;br /&gt;
&lt;br /&gt;
I need to give you this background so that you will know that there is a very good chance that I will think the program needs work when the truth is that the user's inexperience is the real problem.&lt;br /&gt;
&lt;/blockquote&gt;He proceeded to explain how he uses IRC, first with xchat&lt;sup&gt;[&lt;a href="#bm-xchat"&gt;4&lt;/a&gt;]&lt;/sup&gt;, and then with ayttm.  He went into great detail, starting from how he launched the program to how he got to his final intended task, how much time it took him to cover each task, the problems he saw along the way, the kind of internet connection he was using, and finally some suggestions and opinions.  For each of them he explained how it would help him and others like him, and how important it was to him relative to the other problems he saw.&lt;br /&gt;
&lt;br /&gt;
He closed telling us that he was really happy with ayttm, inspite of the problems he faced, and if we could fix the problems he listed, it could become a core part of the Puppy Linux distribution.&lt;br /&gt;
&lt;blockquote&gt;... I am amazed at the level of functionality you have put into a small package. Please keep up the good work.&lt;br /&gt;
&lt;br /&gt;
I hope you find something of use in all this,&lt;br /&gt;
&lt;br /&gt;
George&lt;br /&gt;
&lt;/blockquote&gt;In all, his email worked out to 5 printed pages.&lt;br /&gt;
&lt;br /&gt;
I thanked him for his report.  It was easily the best problem report we'd ever received on ayttm.  All past reports read something like, "Foo doesn't work for me", and were typically no longer than 3 lines, and included no description of the environment under which it was run.&lt;br /&gt;
&lt;br /&gt;
George's message included a lot of detail of the problem itself, but it was composed in a very friendly, almost self-deprecating tone, suggesting that it's quite possible that all the problems he sees are really PEBKACs&lt;sup&gt;[&lt;a href="#bm-pebkac"&gt;5&lt;/a&gt;]&lt;/sup&gt;.  He never once sounded condescending, or as if he was doing us a service by writing up this report, and he threw just enough flattery to make us feel good, but not too much that we felt he was trying to play us.  Most importantly, he'd by far put more effort into writing the report than any other bug reporter had.&lt;br /&gt;
&lt;br /&gt;
He didn't pester us further to find out whether we were going to implement what he asked, or when it was going to be done, but he stayed in touch on the fringe, playing ayttm representative on the puppy linux forums.&lt;br /&gt;
&lt;br /&gt;
In the meanwhile, Barry, the author of Puppy Linux sent us a few patches.&lt;br /&gt;
&lt;br /&gt;
I should mention here, that since ayttm implemented the Yahoo! Messenger protocol, and I was (and still am) employed at Yahoo!, I couldn't contribute any code to the project (I'd worked on ayttm from the start before joining Yahoo!), however, as all the problems George reported related to IRC, an open protocol that predated Yahoo! by a long time, it was deemed okay for me to support this part of the effort with design comments, code reviews and some amount of requirements analysis.  This meant that Siddhesh, the only developer at the time, could spend all his time hacking.&lt;br /&gt;
&lt;br /&gt;
Siddhesh spent some time rewriting all of IRC support, and passed on an alpha to George and Barry to test.  About a week later, George got back to us with a complete log of his IRC session running ayttm in debug mode.  It was now early June.&lt;br /&gt;
&lt;h4&gt;Rejection&lt;/h4&gt;We also started chatting on IRC around that time, and he said he wanted to do more than just file bug reports and send in debug logs.  He used to be a programmer, and though the language was different, the logic's more or less the same.&lt;br /&gt;
&lt;br /&gt;
I told him which source file he could look at to find the feature that bugged him the most, and he sent in his first patch a little while later.  It looked like this:&lt;br /&gt;
&lt;pre&gt;- /* get list of channels */
-       ret = sendall(ila-&gt;fd, "LIST\n", strlen("LIST\n"));
- 
+ /* get list of channels  commented out GWB per PST 7Jun2008
+  *    ret = sendall(ila-&gt;fd, "LIST\n", strlen("LIST\n"));
+  * 
+  * and following line added
+  */
+    irc_finish_login(ila);
&lt;/pre&gt;Not a big deal you might think.  It actually cuts out a feature in fact.  But what it really does, is allow someone to use ayttm for IRC without timing out.  So, sure, he used spaces instead of tabs for indentation, but that was fine.  The most important thing is that he was now so invested in this, and he'd got his foot in the door, he didn't want to stop.&lt;br /&gt;
&lt;br /&gt;
His patch was not accepted, and Siddhesh explained why (it broke the room list dialog), but Siddhesh also had an alternate fix for the problem that he asked George to test.&lt;br /&gt;
&lt;h4&gt;Come back&lt;/h4&gt;Many new developers get turned off at this point.  It takes a lot of effort to create your first patch, and a lot of self-confidence to group of people that you know only by their mystical handles and semi revere for doing things that you can't.  Getting a rejection at that point can set you back on both counts.  Not George.  We chatted some more, and he set to work on the next thing that bugged him.  This is what he posted to the list:&lt;br /&gt;
&lt;blockquote&gt;... I have made some changes to offline_queue_mgmt.c.  The diff file is attached.&lt;br /&gt;
&lt;br /&gt;
Bluesmoon says that with my changes he always gets auto logged in.  My own results are more random, although I sometimes get autolog. I suspect Ayttm? recognizes bluesmoon by his keyboard touch and remembers him fondly ( he is a former Ayttm? developer ), and treats him better than me.&lt;br /&gt;
&lt;/blockquote&gt;Again, there's that bit of humour in there that suggests he's having fun doing this.  Happy developers write good code.  His patch got in.&lt;br /&gt;
&lt;br /&gt;
Now in mid-June, he sent an update&lt;sup&gt;[&lt;a href="#bm-george-update"&gt;6&lt;/a&gt;]&lt;/sup&gt; on the status of his tests, this time addressed at Siddhesh:&lt;br /&gt;
&lt;blockquote&gt;Siddhesh,&lt;br /&gt;
&lt;br /&gt;
As you know, I have been downloading the latest source and testing it almost as quickly as you commit. I have been testing your tagged branch libirc-mod. I thought I'd take a minute to document the current Ayttm? status....&lt;br /&gt;
&lt;/blockquote&gt;&lt;h4&gt;The name&lt;/h4&gt;Apart from his first email to us, George always put a question mark at the end of Ayttm.  He now suggested that we add the question mark permanently as part of the name as an allusion to what it stands for ("Are you talking to me?").  Neither Siddhesh, nor I thought it was a good idea because as it turns out, many fonts use the ? character when they don't have a glyph to display for a particular character (others use a box), and we didn't want to confuse users with this.  Another rejection of George's ideas, but he realised that while we were turning down his ideas, we weren't turning him down.&lt;br /&gt;
&lt;br /&gt;
One thing that a lot of individuals forget about when communicating over email, IM or IRC, is that the person with the idea is not the same as the idea.  This holds for both, the individual with the idea, and the individuals reacting to it.  I've seen too many cases where either the person proposing an idea was attacked because the idea wasn't liked, or the person proposing the idea took a rebuttal of their idea too personally and thought that everyone hated them.  George didn't have these notions, and his attitude in email made it impossible for us to feel any animosity towards him.&lt;br /&gt;
&lt;h4&gt;The Pup&lt;/h4&gt;In July, George posted this message&lt;sup&gt;[&lt;a href="#bm-george-july"&gt;7&lt;/a&gt;]&lt;/sup&gt; to the list:&lt;br /&gt;
&lt;blockquote&gt;This was just posted on the Puppy Linux lead developer's blog.&lt;br /&gt;
&lt;br /&gt;
Ayttm will be builtin in the next alpha release of Puppy Linux.&lt;br /&gt;
&lt;br /&gt;
Feels like a big win to me - I don't know why - I didn't write it.&lt;br /&gt;
&lt;/blockquote&gt;Indeed, George was way more pleased than we were.  I'd guess it had to do with seeing two projects that he cared deeply about getting so closely coupled.  Almost like watching two of your close friends getting hitched.  The ayttm dev team still knew very little about Puppy Linux (I was a RHEL &amp; Ubuntu user, and Siddhesh worked at RedHat).  George, on the other hand, made it happen.&lt;br /&gt;
&lt;br /&gt;
George turned into our liaison on the Puppy Linux forums.  He'd collect bug reports from Puppy Linux users, verify them and then pass them on to the ayttm bug tracker on sourceforge.  We chatted quite a bit over the next few months about new features he wanted to add and bugs he wanted fixed, what he thought of the changes.  At one point I suggested that he speak about his experiences with ayttm at a conference&lt;sup&gt;[&lt;a href="#bm-fossin"&gt;8&lt;/a&gt;]&lt;/sup&gt; in India.  Siddhesh and some of the other developers were doing talks of their own.  He considered it, but decided against it because of his age.&lt;br /&gt;
&lt;br /&gt;
It was only then that I found out how old he was.  I won't reveal that here since it was in a private conversation, but I have a fair way to go before I get there, and I hope I'm as enthusiastic as he is when I do.&lt;br /&gt;
&lt;br /&gt;
I haven't heard from George in a while, but I've also stopped monitoring the ayttm bug tracker, so perhaps he's active there.&lt;br /&gt;
&lt;br /&gt;
I should also mention as an afterthought, that even though I've referred to George as "he" throughout this post, I don't actually know if I was speaking with a man or a woman.  It never came up, it was never important, and knowing it wouldn't have changed anything.  I assumed he was a man because George is most commonly a man's name.  Back in India, the only time I'd ever heard of George as a girl's name was in Enid Blyton's Famous Five&lt;sup&gt;[&lt;a href="#bm-famous-five"&gt;9&lt;/a&gt;]&lt;/sup&gt;.  And in that, I learnt another lesson from George.&lt;br /&gt;
&lt;br /&gt;
When it comes to hacking on opensource software, none of age, gender, race, country of origin, or how you look matters.  All that matters is a pleasant attitude to your fellow developers, a willingness to keep at it and learn as you go, the drive to not give up when things don't go your way, and the ability to tell the difference between an idea and the one who has it.&lt;br /&gt;
&lt;br /&gt;
Thanks George.  To answer your first email, yes I did find much of use in this.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;References&lt;/h4&gt;&lt;ol class="ref"&gt;&lt;li id="bm-george-email"&gt;&lt;a href="http://sourceforge.net/mailarchive/message.php?msg_id=19228158"&gt;George's first email to ayttm-users&lt;/a&gt;.  Yes, we use sourceforge.  It's not pretty, but it's all we had at the time.&lt;/li&gt;
&lt;li id="bm-puppy"&gt;&lt;a href="http://www.puppylinux.com/"&gt;Puppy Linux&lt;/a&gt;, a small, fast and easy to use linux distro&lt;/li&gt;
&lt;li id="bm-ayttm"&gt;&lt;a href="http://ayttm.sourceforge.net/"&gt;Ayttm&lt;/a&gt; - Are you talking to me? A universal instant messenger for unix&lt;/li&gt;
&lt;li id="bm-xchat"&gt;&lt;a href="http://xchat.org/"&gt;xchat&lt;/a&gt; an IRC chat client for X.&lt;/li&gt;
&lt;li id="bm-pebkac"&gt;&lt;a href="http://catb.org/~esr/jargon/html/P/PEBKAC.html"&gt;PEBKAC&lt;/a&gt; in the Jargon File.&lt;/li&gt;
&lt;li id="bm-george-update"&gt;&lt;a href="http://sourceforge.net/mailarchive/message.php?msg_id=19671193"&gt;George's update on June 19, 2008&lt;/a&gt;.&lt;br /&gt;
&lt;li id="bm-george-july"&gt;&lt;a href="http://sourceforge.net/mailarchive/message.php?msg_id=19839436"&gt;Ayttm on Puppy Linux&lt;/a&gt;.  In July, George announced that ayttm had become part of Puppy.&lt;/li&gt;&lt;li id="bm-fossin"&gt;&lt;a href="http://foss.in/"&gt;FOSS.IN&lt;/a&gt; - India's largest community run conference on free and opensource software.&lt;/li&gt;&lt;li id="bm-famous-five"&gt;Enid Blyton, &lt;a href="http://www.enidblyton.net/famous-five/"&gt;The Famous Five&lt;/a&gt;. 1942-1963.&lt;/li&gt;&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=2oaNA8s4y4I:LzNbb7jkorM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=2oaNA8s4y4I:LzNbb7jkorM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=2oaNA8s4y4I:LzNbb7jkorM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=2oaNA8s4y4I:LzNbb7jkorM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=2oaNA8s4y4I:LzNbb7jkorM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/2oaNA8s4y4I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/192574653044358069/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/05/story-of-george-ayttms-most-prolific.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/192574653044358069?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/192574653044358069?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/2oaNA8s4y4I/story-of-george-ayttms-most-prolific.html" title="The story of George &amp;mdash; ayttm's most prolific non-developing contributor" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/05/story-of-george-ayttms-most-prolific.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHQH47eCp7ImA9WhZXE0o.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-2669721427649372476</id><published>2011-05-02T16:04:00.000-07:00</published><updated>2011-05-02T16:08:51.000-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-02T16:08:51.000-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cookies" /><category scheme="http://www.blogger.com/atom/ns#" term="ssl" /><category scheme="http://www.blogger.com/atom/ns#" term="twitter" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><category scheme="http://www.blogger.com/atom/ns#" term="firesheep" /><title>Twitter, SSL and #poopin</title><content type="html">Watching the &lt;a href="https://twitter.com/"&gt;twitter&lt;/a&gt; feed about &lt;a href="https://twitter.com/search?q=jsconf"&gt;#jsconf&lt;/a&gt; shows a lot of people tweeting about #poopin.  Turns out that someone's been stealing twitter cookies using a &lt;a href="http://codebutler.com/firesheep"&gt;firesheep&lt;/a&gt; like tool and tweeting on their behalf.  The tweets aren't malicious in nature, and are geared more at educating the user about the need to use SSL or some kind of encrypted tunnel when tweeting over untrusted wireless connections.&lt;br /&gt;
&lt;br /&gt;
Here's the problem.  Even people who do know the risks, and take the trouble to use twitter over SSL will get caught because of certain bugs with twitter's handling of their SSL pages.&lt;br /&gt;
&lt;br /&gt;
If you visit https://mobile.twitter.com/, this is what you'd get: (shown in a browser so I could hilight the URL bar)&lt;br /&gt;
&lt;div style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-OFx0Vv6u58o/Tb82PCSwXCI/AAAAAAAAALg/CXF3gQATdBI/twitter-m-1.png"&gt;&lt;/div&gt;&lt;br /&gt;
Click Sign in and this is what you get:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-ylPbnUAPR00/Tb82PRU0dJI/AAAAAAAAALk/vS_jCqrtN_A/twitter-m-2.png"&gt;&lt;/div&gt;&lt;br /&gt;
Sign in, and this is what you get:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-RDc18A_KVCM/Tb82PpnflII/AAAAAAAAALo/gbRtUNmbAEQ/twitter-m-3.png"&gt;&lt;/div&gt;&lt;br /&gt;
Notice that the post sign-in URL is no longer https, but is now http.&lt;br /&gt;
&lt;br /&gt;
At various points of time, trying this through my mobile phone, I get redirected from an https site to an http site when I do some of the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Replying to a tweet&lt;/li&gt;
&lt;li&gt;Replying to a direct message (seems to be fixed)&lt;/li&gt;
&lt;li&gt;Retweeting (with/without? JavaScript)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
If you search through the page source on https://mobile.twitter.com/ for the string "http://", you'll find a few instances in comments, but then these interesting ones in a JSON object:&lt;br /&gt;
&lt;pre&gt;"twitterApiBase":"http://api.twitter.com"
"apiBase":"http://api.local.twitter.com:9000"
"twitterBase":"http://twitter.com"
"mobileBase":"http://mobile.twitter.com"
&lt;/pre&gt;I haven't examined the code in detail to see how these are used, but it seems to suggest that at least some calls are going out over http, and since they're all on the twitter.com domain, your twitter cookies get sent along.&lt;br /&gt;
&lt;br /&gt;
Now this is only the twitter mobile website.  Mobile clients could be another matter, and the desktop site could also have problems.  I haven't tested.  Personally, I try to either use a VPN, or only tweet using SMS, but I have been caught by something like this before (at FOSS.IN/2010) which is when I started to study the problem.&lt;br /&gt;
&lt;br /&gt;
Also, it doesn't matter if you've configured twitter to always use HTTPS.  It still has this problem.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=5UQUbMm7Ikk:mwmwsUd2qTA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=5UQUbMm7Ikk:mwmwsUd2qTA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=5UQUbMm7Ikk:mwmwsUd2qTA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=5UQUbMm7Ikk:mwmwsUd2qTA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=5UQUbMm7Ikk:mwmwsUd2qTA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/5UQUbMm7Ikk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/2669721427649372476/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/05/twitter-ssl-and-poopin.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2669721427649372476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2669721427649372476?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/5UQUbMm7Ikk/twitter-ssl-and-poopin.html" title="Twitter, SSL and #poopin" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-OFx0Vv6u58o/Tb82PCSwXCI/AAAAAAAAALg/CXF3gQATdBI/s72-c/twitter-m-1.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/05/twitter-ssl-and-poopin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIAR345fip7ImA9WhZQFk4.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-7090767563275001261</id><published>2011-04-24T02:30:00.000-07:00</published><updated>2011-04-24T02:32:26.026-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-24T02:32:26.026-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="png" /><category scheme="http://www.blogger.com/atom/ns#" term="c" /><category scheme="http://www.blogger.com/atom/ns#" term="hack" /><category scheme="http://www.blogger.com/atom/ns#" term="gradient" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>pngtocss and getting back to basics</title><content type="html">A couple of days ago &lt;a href="http://www.stubbornella.org/content/"&gt;Nicole&lt;/a&gt; tweeted about the &lt;a href="http://twitter.com/stubbornella/status/61499795801505792/"&gt;absence of a tool to convert images to gradients&lt;/a&gt;.  I didn't see the tweet right away because I was asleep at the time, but &lt;a href="http://www.sergeychernyshev.com/"&gt;Sergey&lt;/a&gt; retweeted later it under the &lt;a href="http://twitter.com/perfplanet"&gt;@perfplanet&lt;/a&gt; account and I caught that.&lt;br /&gt;
&lt;br /&gt;
My first thought was that there really must be something like that.  Why not just use the gimp's colour picker or something.  My second thought was, "what the heck are CSS gradients?" followed closely by, "I've never read a PNG in C before".  &lt;br /&gt;
&lt;h4&gt;Back to basics&lt;/h4&gt;All of this brought up a sense of déjà vu back to 1999, to the birth of my &lt;a href="http://httptype.sourceforge.net/"&gt;first opensource project&lt;/a&gt;.  That started out with someone on the ilug-bom mailing list asking how he could find out which server was running on a given host.  I started to type out an explanation and then figured that it would take me less time to hack up a solution in perl, so I did, and &lt;code&gt;httptype&lt;/code&gt; was born.&lt;br /&gt;
&lt;br /&gt;
Yesterday was very similar, the only real difference being that this time I knew how to use version control, so I jumped in with:&lt;br /&gt;
&lt;pre&gt;mkdir pngtocss
cd pngtocss
git init
mkdir src
&lt;/pre&gt;And then started on a bit of research.  First to find out how to read in a PNG.&lt;br /&gt;
&lt;h4&gt;Reading in a PNG&lt;/h4&gt;libpng.org has a great book on using the libpng library.  It's a long book and I'm a lazy dev, so I didn't read the whole thing.  Instead I found the Chapter that dealt specifically with reading a PNG into memory.  It turned out to be &lt;a href="http://www.libpng.org/pub/png/book/chapter13.html"&gt;Chapter 13&lt;/a&gt;.  Now when I say "I found", I really mean that Yahoo! found it for me.&lt;br /&gt;
&lt;br /&gt;
Anyway, I read the doc and it was pretty straightforward, so I jumped right into writing code, but guess what?  My C programming skills were rusty.  My Makefile skills more so.  Having &lt;code&gt;man&lt;/code&gt; at hand helped things move along and I was soon up to speed.&lt;br /&gt;
&lt;br /&gt;
Once I had an in-memory array of the image's pixels, I had to figure out how to write out the CSS.&lt;br /&gt;
&lt;h4&gt;CSS gradients&lt;/h4&gt;There were a few sites that helped with this, in particular &lt;a href="http://css-tricks.com/css3-gradients/"&gt;CSS tricks&lt;/a&gt;.  A few printfs later and I had simple gradients done.&lt;br /&gt;
&lt;br /&gt;
The code was simple, and handled a very specific case.  It didn't work with all possible gradients, and wouldn't be able to handle a sprite, but this is how projects grow.  You don't try to solve everything at the start.  You solve a use case and push it out there to find out what people want.&lt;br /&gt;
&lt;br /&gt;
The last time around I pushed it out to the mailing list and got a lot of feedback, patches and even a mentor.  This time I announced it on twitter and got a bunch of feedback and a ton of retweets.&lt;br /&gt;
&lt;h4&gt;The physics of gradients&lt;/h4&gt;Today I decided to look at multi-colour gradients.  Not because anyone had asked for it, but because I thought it might be interesting to figure out where a colour shows up.&lt;br /&gt;
&lt;br /&gt;
Now there are various ways to look at a gradient.  If you think about it from a physics background, it's essentially a particle moving with constant velocity.  Each pixel position is a unit of time and the colour value is the particle's position at that point in time.  The position at any point of time is calculated by the second equation of motion:&lt;br /&gt;
&lt;pre class="eqn"&gt;s = ut + ½at²
&lt;/pre&gt;For a simple two colour gradient, there's no acceleration, and the velocity &lt;em&gt;u&lt;/em&gt; is the difference in the two colours divided by the number of pixels in that direction.  This is the same as the difference in colour of adjacent pixels (colour differential per unit pixel).&lt;br /&gt;
&lt;br /&gt;
The cool thing is that for CSS, you only need to specify the end points and it will fill in everything else.&lt;br /&gt;
&lt;h4&gt;Multi-colour gradients&lt;/h4&gt;When dealing with multi-colour gradients, you need to figure out where the stop points are.  Once you know what the colour velocity at the start of the gradient, you keep iterating through the image until the velocity is no longer what you expect it to be.  This is a colour stop.  Note down the new colour and its position and restart.&lt;br /&gt;
&lt;br /&gt;
To speed things up, rather than look at every pixel along the way, I exponentially increase the pixel index that I look at until I hit a bump and then backtrack till I find what I was looking for.  A sort of binary search.&lt;br /&gt;
&lt;br /&gt;
Putting it all together, I ended up with &lt;a href="http://bluesmoon.github.com/pngtocss/examples/example.html"&gt;this example page&lt;/a&gt; which has gradient images and the equivalent CSS gradient side by side.  There are still limitations, but none that I care to fix at the moment.&lt;br /&gt;
&lt;h4&gt;Other tools&lt;/h4&gt;Also of note is Alex Sirota's &lt;a href="http://www.colorzilla.com/gradient-editor/"&gt;Gradient Editor&lt;/a&gt; as part of Colorzilla.  It's completely web-based and can also take in a file upload and generate a gradient from that.  It doesn't handle the rainbow gradient yet, but I suppose it won't be too hard to get around that.&lt;br /&gt;
&lt;h4&gt;pngtocss&lt;/h4&gt;In any case, pngtocss is on github at &lt;a href="https://github.com/bluesmoon/pngtocss"&gt;https://github.com/bluesmoon/pngtocss&lt;/a&gt;, feel free to fork it and submit patches.  The code isn't pretty and isn't really commented either.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=qCislAw__f0:KtqoCB1cbPE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=qCislAw__f0:KtqoCB1cbPE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=qCislAw__f0:KtqoCB1cbPE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=qCislAw__f0:KtqoCB1cbPE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=qCislAw__f0:KtqoCB1cbPE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/qCislAw__f0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/7090767563275001261/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/04/pngtocss-and-getting-back-to-basics.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7090767563275001261?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/7090767563275001261?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/qCislAw__f0/pngtocss-and-getting-back-to-basics.html" title="pngtocss and getting back to basics" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/04/pngtocss-and-getting-back-to-basics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YMQX89fip7ImA9WhZRF04.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-1689316740966047711</id><published>2011-04-13T15:44:00.000-07:00</published><updated>2011-04-13T15:53:00.166-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-13T15:53:00.166-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="widgets" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>How much do you trust third party widgets?</title><content type="html">It's fairly common to find third party widgets installed on websites today.  My own blog includes widgets from twitter, delicious, google analytics and google translate, and in the past I've included mybloglog and technorati as well.  The facebook like button, facebook comments, disqus comments, badges from sharethis and more are all over the place.  This is a great way to engage with your readers, get feedback from them, and let them get the word out about your site, but how secure is it?  When we include a third party widget on our sites, what exactly do we trust the third party to do and not do?&lt;br /&gt;
&lt;br /&gt;
In particular, this mostly refers to widgets that require you to add links to their JavaScript into your page using a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; node.  There are a few that work through iframes, and while there are still a few issues with that, the script nodes are the ones that can do you the most damage.&lt;br /&gt;
&lt;h4&gt;Not be evil&lt;/h4&gt;For starters, we trust the third party to not be evil.  We trust that the JavaScript they serve us will:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;not try to steal the data our users give us through the website,&lt;/li&gt;
&lt;li&gt;not manipulate our page content in malicious ways,&lt;/li&gt;
&lt;li&gt;not track our user's actions in any ways that we haven't authorised them to do,&lt;/li&gt;
&lt;li&gt;probably more...&lt;/li&gt;
&lt;/ul&gt;For the most part, the widget provider stakes their reputation on the quality and the &lt;em&gt;chastity&lt;/em&gt; of the widgets they provide.  Anything malicious found in their widgets would affect a large number of sites, but would cause terrible PR and contractual problems for the provider.  For most of us small blog authors, dots on the long tail as it were, the widget provider has far more to lose than we do.  For a large company, like say one of these widget providers themselves, though, there's much more at stake, so don't be surprised if you don't see third party widgets on Google, Yahoo!, Microsoft, Facebook, Twitter, Amazon, Ebay and any other large site you can think of.  They probably have much more (or at the least an equal amount) to lose than the widget provider.&lt;br /&gt;
&lt;h4&gt;Not be careless&lt;/h4&gt;We're also trusting the widget provider to not be careless.  We expect them to be diligent about the security of their own systems.  If someone malicious were to break into a third party widget provider, they could then manipulate the JavaScript served out to our sites.  Same problem as above, same repercussions, but slightly different entity responsible.  It's possible for the widget owner in this case to claim that they were also the victim.  That doesn't make it better for anyone, it just shifts the blame.&lt;br /&gt;
&lt;h4&gt;Not be too trusting&lt;/h4&gt;We don't just trust the widget provider, but also their hosting provider and their DNS registrar.  This is a sub-topic under the don't be careless part above, but there may be another entity involved here.  Running a whois lookup on the widget provider's hostname will tell you who their DNS registrar is.  Do you trust them to not get compromised and have DNS redirected?  Does the widget provider use SSL to guarantee that the host you're connecting to is in fact a host they own?  Can you trust SSL?&lt;br /&gt;
&lt;h4&gt;Not go down&lt;/h4&gt;Let's face it... how many times have you had a twitter (or any other) widget on your page that showed nothing?  Perhaps you're being rate limited, perhaps the service is down for maintenance, or something else.  That huge blank space where your widget should be looks kinda bad.  Not really a security issue, but it hurts your site's image.&lt;br /&gt;
&lt;br /&gt;
There's little doubt why large companies won't trust a third party's JavaScript on their own sites.  In exceptional cases, they may contract with the third party to get the JavaScript onto their own servers where they can guarantee that it doesn't change, and can pull the plug quickly if something goes wrong.&lt;br /&gt;
&lt;br /&gt;
What about you?  Do you run a website that includes third party widget JavaScript on your site?  Are you big or small?  Would you keep this up when you became big?&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=lKtSUWjdXR8:PdFTX-wmneo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=lKtSUWjdXR8:PdFTX-wmneo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=lKtSUWjdXR8:PdFTX-wmneo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=lKtSUWjdXR8:PdFTX-wmneo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=lKtSUWjdXR8:PdFTX-wmneo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/lKtSUWjdXR8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/1689316740966047711/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/04/how-much-do-you-trust-third-party.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1689316740966047711?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1689316740966047711?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/lKtSUWjdXR8/how-much-do-you-trust-third-party.html" title="How much do you trust third party widgets?" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/04/how-much-do-you-trust-third-party.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IESX0zcSp7ImA9WhZRFEs.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-1237531878943949764</id><published>2011-04-09T19:15:00.000-07:00</published><updated>2011-04-10T14:05:08.389-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-10T14:05:08.389-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="webkit" /><category scheme="http://www.blogger.com/atom/ns#" term="bug" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>overflow:hidden, border-radius and position:absolute</title><content type="html">In my &lt;a href="http://tech.bluesmoon.info/2011/03/overflowhidden-and-border-radius-on.html"&gt;last post&lt;/a&gt;, I showed off some CSS fun with border-radius and overflow:hidden.  Truth be told, that post started out about a bug with WebKit based browsers in relation to those attributes, but when I got down to writing the post, I couldn't reproduce the bug.  Today, while trying to animate it, I managed to isolate the problem, and it turns out that I'm not the only one.&lt;br /&gt;
&lt;br /&gt;
The problem in brief is that the contents of a container with overflow:hidden will still overflow its border if you have border-radius set and position set to anything other than static.  &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=50072"&gt;Bug 50072&lt;/a&gt; on WebKit describes a similar issue in more detail, and I've posted my comments at the bottom of that bug.  I've created a minimal &lt;a href="http://jsfiddle.net/5dGAt/2/"&gt;test case&lt;/a&gt; on JSFiddle.  This is what it looks like on a webkit based browser:&lt;br /&gt;
&lt;img src="https://img.skitch.com/20110410-1mqu5wwr3infmyw1caudbiqh83.png" alt="[WebKit overflow bug with border-radius]"&gt;&lt;br /&gt;
Like I said, the problem only shows up when you set the container's position style attribute to something other than static (which is the default).&lt;br /&gt;
&lt;br /&gt;
I've tested in the latest versions of Firefox, Chrome, Safari and Opera, and Firefox is the only one that renders it correctly.&lt;br /&gt;
&lt;br /&gt;
Now before you go asking me to test on the latest WebKit, rest assured that it's compiling as I write this.  I'll try and submit a fix if it still exists and I can figure out what needs patching, but given that position:static works correctly, it may just be a matter of seeing what's different with those two flows.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=rnwh-Q_ymII:62XPkE5X5xA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=rnwh-Q_ymII:62XPkE5X5xA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=rnwh-Q_ymII:62XPkE5X5xA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=rnwh-Q_ymII:62XPkE5X5xA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=rnwh-Q_ymII:62XPkE5X5xA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/rnwh-Q_ymII" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/1237531878943949764/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/04/overflowhidden-border-radius-and.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1237531878943949764?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/1237531878943949764?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/rnwh-Q_ymII/overflowhidden-border-radius-and.html" title="overflow:hidden, border-radius and position:absolute" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/04/overflowhidden-border-radius-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAESXc8eip7ImA9WhZSFUQ.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-3377474586900830785</id><published>2011-03-30T01:20:00.000-07:00</published><updated>2011-03-31T11:05:08.972-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-31T11:05:08.972-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>overflow:hidden and border-radius</title><content type="html">So what exactly needs to happen when you set &lt;code&gt;overflow:hidden&lt;/code&gt; on a container element?  At which pixel point do the element's contents get hidden?  Is it at the padding, the inside of the border, the outside of the border, the outline or somewhere else?&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.w3.org/TR/css3-background/#corner-clipping"&gt;The spec&lt;/a&gt; sort of states that it's at the border or padding (depending on background-clip):&lt;br /&gt;
&lt;blockquote&gt;Other effects that clip to the border or padding edge (such as ‘overflow’ other than ‘visible’) also must clip to the curve.&lt;br /&gt;
&lt;/blockquote&gt;With that in mind, I decided to throw rounded corners into the fray and have some fun:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="globe" style="border: solid 0px black;height:200px;width:200px;text-align:justify;font-size:6pt;line-height:7pt;overflow:hidden;color:brown;-webkit-border-radius:100px;-moz-border-radius:100px;border-radius:100px;"&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?&lt;br /&gt;
&lt;/div&gt;Caveat: Opera is broken.&lt;br /&gt;
&lt;br /&gt;
Anyone wanna try a deathstar?&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=OreemmRRDKs:enlZzCwuguI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=OreemmRRDKs:enlZzCwuguI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=OreemmRRDKs:enlZzCwuguI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=OreemmRRDKs:enlZzCwuguI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=OreemmRRDKs:enlZzCwuguI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/OreemmRRDKs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/3377474586900830785/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/03/overflowhidden-and-border-radius-on.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3377474586900830785?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3377474586900830785?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/OreemmRRDKs/overflowhidden-and-border-radius-on.html" title="overflow:hidden and border-radius" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/03/overflowhidden-and-border-radius-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08FRXs5eyp7ImA9WhZSE00.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-3275004390274858002</id><published>2011-03-28T01:42:00.000-07:00</published><updated>2011-03-28T01:43:34.523-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-28T01:43:34.523-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="network" /><category scheme="http://www.blogger.com/atom/ns#" term="MAC" /><category scheme="http://www.blogger.com/atom/ns#" term="privacy" /><category scheme="http://www.blogger.com/atom/ns#" term="spoofing" /><category scheme="http://www.blogger.com/atom/ns#" term="macosx" /><title>Spoofing your MAC address on MacOSX 10.6</title><content type="html">There are various reasons why one might need to spoof ones &lt;abbr title="Media Access Control"&gt;MAC&lt;/abbr&gt; address.  For example, your ISP may have bound your connection to your MAC address, and then you had to change your network card because the old one was fried by a lightning strike (this actually happened to me).  Another reason is privacy.  You may want to change your MAC address if you're surfing the net from a coffee shop with free wifi to make sure no one sniffing the network can identify you.  Whatever the reason, the actual commands to (temporarily) change your MAC address are quite straightforward.&lt;br /&gt;
&lt;br /&gt;
Note that these commands work on Linux, FreeBSD and MacOSX (at least versions greater than 10.5).&lt;br /&gt;
&lt;br /&gt;
Before you do anything, make sure the port is up:&lt;br /&gt;
&lt;pre&gt;sudo ifconfig &amp;lt;iface&amp;gt; up
&lt;/pre&gt;Where &lt;code&gt;iface&lt;/code&gt; is the network interface.  This should be something like &lt;code&gt;en0&lt;/code&gt; for the ethernet port on MacOSX, or &lt;code&gt;eth0&lt;/code&gt; for a linux box, etc.  If you're not sure, just run the &lt;code&gt;ifconfig&lt;/code&gt; command without any arguments... although if you're not sure, you probably shouldn't be doing this anyway ;)&lt;br /&gt;
&lt;br /&gt;
Now, once your interface is up, you can change its MAC address.  This only lasts until the next reboot, but given that I almost never shutdown my laptop, it's as good as permanent.&lt;br /&gt;
&lt;br /&gt;
For the ethernet port:&lt;br /&gt;
&lt;pre&gt;sudo ifconfig en0 ether &amp;lt;new MAC address&amp;gt;
&lt;/pre&gt;This works even if you're currently connected to a network.&lt;br /&gt;
&lt;br /&gt;
For the wireless card, first disconnect from any wireless networks.  I've found that the easiest way to do this is to try to connect to a network that doesn't exist.  From your Airport icon in the menu bar, choose "Join Other Network", and type in some random string.  Note that you don't need to do this if your airport doesn't automatically connect to a wireless network.&lt;br /&gt;
&lt;br /&gt;
Once you've disconnected, just run the command as above, but for the &lt;code&gt;en1&lt;/code&gt; interface:&lt;br /&gt;
&lt;pre&gt;sudo ifconfig en1 ether &amp;lt;new MAC address&amp;gt;
&lt;/pre&gt;You can now reconnect to any wireless network.&lt;br /&gt;
&lt;br /&gt;
Note that even though this is temporary, I do have it set up to be more or less permanent on Ubuntu through my network startup scripts.  I'll publish them some other time.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=iKbAQu2-Qig:bTzRpHk0HaE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=iKbAQu2-Qig:bTzRpHk0HaE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=iKbAQu2-Qig:bTzRpHk0HaE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=iKbAQu2-Qig:bTzRpHk0HaE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=iKbAQu2-Qig:bTzRpHk0HaE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/iKbAQu2-Qig" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/3275004390274858002/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/03/spoofing-your-mac-address-on-macosx-106.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3275004390274858002?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/3275004390274858002?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/iKbAQu2-Qig/spoofing-your-mac-address-on-macosx-106.html" title="Spoofing your MAC address on MacOSX 10.6" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/03/spoofing-your-mac-address-on-macosx-106.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMFQnk-eCp7ImA9WhZSEk8.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-2216185099918216805</id><published>2011-03-27T03:06:00.000-07:00</published><updated>2011-03-27T03:06:53.750-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-27T03:06:53.750-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="htc" /><category scheme="http://www.blogger.com/atom/ns#" term="att" /><category scheme="http://www.blogger.com/atom/ns#" term="freestyle" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><category scheme="http://www.blogger.com/atom/ns#" term="phone" /><title>HTC Freestyle: First Impressions</title><content type="html">I got an HTC Freestyle from AT&amp;T today.  It was free, so I can't complain about the price, however it's a bit of a downgrade from my E71.  First, what I like about it.&lt;br /&gt;
&lt;br /&gt;
It has a decently sized touchscreen, and the Twitter+Facebook app is pretty decent.  The browser is WebKit based and handles &lt;a href="http://tech.bluesmoon.info/2011/01/device-width-and-how-not-to-hate-your.html"&gt;CSS @media queries&lt;/a&gt; correctly.  It even switches correctly when you rotate, which the iPhone gets wrong.&lt;br /&gt;
&lt;br /&gt;
On the downside though, rotating from portrait to landscape is not automatic.  You need two clicks to tell the browser that you've rotated.  No accelerometer in this phone.  Which brings us to the things I don't like about it.&lt;br /&gt;
&lt;br /&gt;
No GMail and GMaps apps for it.  Since the primary reason I went in for a smartphone was to check my email and use the GPS while I'm on the road, this makes the phone a complete non-starter.  The sales rep at AT&amp;T told me that it was an Android device, but once I got it home and looked it up, it turns out that that isn't true.  It runs something called Brew MP.&lt;br /&gt;
&lt;br /&gt;
Transferring contacts from my older phone is clumsy, but doable.  The main problem here is that I need to use the SIM card to transfer contacts and it just doesn't have enough space for all my contacts.&lt;br /&gt;
&lt;br /&gt;
I could set my ringtone on the E71 to any mp3 file that I had access to.  On the HTC Freestyle, it's limited to files under 300KB.  Seriously.  Kilobytes.  What is this?  The 80's?  My current ring tone on my 3 year old Nokia is 6.4MB.&lt;br /&gt;
&lt;br /&gt;
After using the real keyboard on the E71, the onscreen keyboard on this device is extremely clumsy to use.  I've made mistakes on every occasion that I've needed to use the keyboard.  I even make mistakes trying to hit the backspace key.  I guess I'll get used to this eventually, however one thing to note is that the E71 does far more with just one key than this phone can do with its keyboard.  The main problem is the number of times your hands/fingers need to move in order to type or even to just select menu items.&lt;br /&gt;
&lt;br /&gt;
No wifi. 'Nuff said.&lt;br /&gt;
&lt;br /&gt;
Ok, so that's it for the "Smart" part of the phone.  Now to the phone part.&lt;br /&gt;
&lt;br /&gt;
I tried to make a call when I got out of the AT&amp;T store.  The call dropped after 3 seconds.  Remember, this is right outside the AT&amp;T store.  All the phones inside the store had decent signal strength.  I thought it may have been due to the battery having almost no charge (since it was a new phone), so took it home and charged it up, but it hasn't changed.  On 8 out of 9 calls that I've made so far I've been unable to hear what the other party says though they can hear me.&lt;br /&gt;
&lt;br /&gt;
Switching on the speakerphone requires two clicks after the call connects.  On the E71 it was one click while the phone was ringing.  This makes a big difference because the person at the other end has no idea what's happening while you're switching on the speakerphone.  It also makes it impossible to answer the phone in speaker mode while driving.&lt;br /&gt;
&lt;br /&gt;
The speakerphone sound quality is also pretty bad.  It's not clear when soft, and starts jarring when loud.  There doesn't seem to be an optimum volume setting for it.&lt;br /&gt;
&lt;br /&gt;
All in all, this is not a phone I'd pay for.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=ERuFr9Ohz88:cqdtUYB3HG0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=ERuFr9Ohz88:cqdtUYB3HG0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=ERuFr9Ohz88:cqdtUYB3HG0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=ERuFr9Ohz88:cqdtUYB3HG0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=ERuFr9Ohz88:cqdtUYB3HG0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/ERuFr9Ohz88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/2216185099918216805/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/03/htc-freestyle-first-impressions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2216185099918216805?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/2216185099918216805?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/ERuFr9Ohz88/htc-freestyle-first-impressions.html" title="HTC Freestyle: First Impressions" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/03/htc-freestyle-first-impressions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUER3o4fip7ImA9WhZTFEU.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-5554452628803649048</id><published>2011-03-18T14:03:00.000-07:00</published><updated>2011-03-18T14:03:26.436-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-18T14:03:26.436-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ie" /><category scheme="http://www.blogger.com/atom/ns#" term="xss" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>X-XSS-Protection</title><content type="html">Internet Explorer 8 has a "useful" feature where it tries to detect if a page is under an &lt;abbr title="Cross Site Scripting"&gt;XSS&lt;/abbr&gt; attack.  If it thinks it has detected an attack, it will disable the malicious code and warn the user about it.  Sound good on the surface of it, except that it's often wrong, often with ads.  In most cases with security issues, it's better to err on the side of caution, but what happens here is that IE ends up warning your users about non-existent security issues on your site.  Users lose trust in your site and everyone loses.&lt;br /&gt;
&lt;br /&gt;
If you already take proactive steps to protect your users from XSS attacks, you &lt;strong&gt;SHOULD&lt;/strong&gt; disable the check and warning.  To do this, add the following HTTP header to all your responses:&lt;br /&gt;
&lt;pre&gt;X-XSS-Protection: 0
&lt;/pre&gt;How you do that depends on the server you're using.  For apache, you'd add this to one of your apache conf files:&lt;br /&gt;
&lt;pre&gt;Header add X-XSS-Protection 0
&lt;/pre&gt;TTYL&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7ydoBrDYza4:5Y3gaUFO_6g:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7ydoBrDYza4:5Y3gaUFO_6g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7ydoBrDYza4:5Y3gaUFO_6g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=7ydoBrDYza4:5Y3gaUFO_6g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=7ydoBrDYza4:5Y3gaUFO_6g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/7ydoBrDYza4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/5554452628803649048/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/03/x-xss-protection.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/5554452628803649048?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/5554452628803649048?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/7ydoBrDYza4/x-xss-protection.html" title="X-XSS-Protection" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/03/x-xss-protection.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8FRn47fyp7ImA9Wx9VFE8.&quot;"><id>tag:blogger.com,1999:blog-7715485.post-8727029692836202979</id><published>2011-01-29T14:18:00.000-08:00</published><updated>2011-01-30T13:26:57.007-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-30T13:26:57.007-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="entities" /><category scheme="http://www.blogger.com/atom/ns#" term="url" /><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>Printing unicode characters in web documents</title><content type="html">I often have to look up reference sites to find out how to write a particular character in HTML, JavaScript or CSS when that character isn't on my keyboard.  This post should save me some searching time in future.&lt;br /&gt;
&lt;br /&gt;
To type a character that's not on your keyboard, you need its unicode codepoint in decimal or hexadecimal.  In the examples below, HH means two hexadecimal digits, DD means two decimal digits, HHHH is four hexadecimal digits, and so on.  DD+ means two or more decimal digits, HH+ means two or more hexadecimal digits.&lt;br /&gt;
&lt;h4&gt;HTML&lt;/h4&gt;To type out unicode characters in HTML, use one of the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&amp;amp;#DDD+;&lt;/li&gt;
&lt;li&gt;&amp;amp;#xHHH+;&lt;/li&gt;
&lt;/ul&gt;eg:&lt;br /&gt;
&lt;pre&gt;&amp;#393; == &amp;amp;#393;
&amp;#x189; == &amp;amp;#x189;
&amp;#x2021; == &amp;amp;#x2021;
&lt;/pre&gt;&lt;h4&gt;JavaScript&lt;/h4&gt;To type out unicode characters in JavaScript, use the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;\uHHHH&lt;/li&gt;
&lt;/ul&gt;eg:&lt;br /&gt;
&lt;pre&gt;&lt;script&gt;document.write("\u2021");&lt;/script&gt; == \u2021
&lt;/pre&gt;&lt;h4&gt;CSS&lt;/h4&gt;To print out a unicode character using CSS content, use the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;\HH+&lt;/li&gt;
&lt;/ul&gt;eg:&lt;style type="text/css"&gt;span.x2021:before { content: "\2021"; }&lt;/style&gt;&lt;br /&gt;
&lt;pre&gt;&lt;span class="x2021"&gt;&lt;/span&gt; == \2021
&lt;/pre&gt;(Note: the CSS example that I've used here only works in browsers that support the &lt;code&gt;:before&lt;/code&gt; pseudo class and the &lt;code&gt;content&lt;/code&gt; rule, but in general you can use unicode characters anywhere in CSS.)&lt;br /&gt;
&lt;h4&gt;URL&lt;/h4&gt;URL context is different from HTML context, so I'm including it here.&lt;br /&gt;
&lt;br /&gt;
To print a unicode character into a URL, you need to represent it in UTF-8, using the %HH notation for each byte.&lt;br /&gt;
eg:&lt;br /&gt;
&lt;pre&gt;&amp;#x2021; ==  %E2%80%A1
&amp;#x43b; ==  %D0%BB
&amp;#39; ==  %39
&lt;/pre&gt;This is not something that you want to do by hand, so use a library to do the conversion.  In JavaScript, you can use the &lt;code&gt;encodeURI&lt;/code&gt; or &lt;code&gt;encodeURIComponent&lt;/code&gt; functions to do this for you.&lt;br /&gt;
&lt;h4&gt;End notes&lt;/h4&gt;Use escape sequences only in two cases.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Your editor or keyboard doesn't allow you to type the characters in directly.&lt;/li&gt;
&lt;li&gt;The characters could be misinterpreted as syntax, eg &amp;lt; or &amp;gt; in HTML.&lt;/li&gt;
&lt;/ol&gt;&lt;h4&gt;References and Further Reading&lt;/h4&gt;&lt;ol class="ref"&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/List_of_Unicode_characters"&gt;List of Unicode Characters&lt;/a&gt; on WikiPedia&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/UTF-8"&gt;UTF-8&lt;/a&gt; on WikiPedia&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Unicode_and_HTML"&gt;Unicode and HTML&lt;/a&gt; on WikiPedia&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Unicode_Escape_Sequences"&gt;JavaScript Unicode Escape Sequences&lt;/a&gt; on &lt;em&gt;Mozilla Developer Network&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Richard Ishida. 2005. &lt;a href="http://www.w3.org/International/questions/qa-escapes"&gt;Using Character Escapes in Markup and CSS&lt;/a&gt; in &lt;em&gt;W3C Internationalisation&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=Av84MWkOk60:Bbtr-JlWPlc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=Av84MWkOk60:Bbtr-JlWPlc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=Av84MWkOk60:Bbtr-JlWPlc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bluestech?a=Av84MWkOk60:Bbtr-JlWPlc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bluestech?i=Av84MWkOk60:Bbtr-JlWPlc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bluestech/~4/Av84MWkOk60" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tech.bluesmoon.info/feeds/8727029692836202979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://tech.bluesmoon.info/2011/01/publishing-untypable-characters-to-web.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/8727029692836202979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7715485/posts/default/8727029692836202979?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bluestech/~3/Av84MWkOk60/publishing-untypable-characters-to-web.html" title="Printing unicode characters in web documents" /><author><name>Philip</name><uri>http://www.blogger.com/profile/18075968083522627991</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="21" height="32" src="http://1.bp.blogspot.com/_g7oISy6bcdQ/TT9p8cXOkEI/AAAAAAAAAKU/8fThON2HrfI/s1600/bluesmoon.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://tech.bluesmoon.info/2011/01/publishing-untypable-characters-to-web.html</feedburner:origLink></entry></feed>
