<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>border: solid 1px red;</title><generator>Tumblr (3.0; @solid1pxred)</generator><link>http://blog.solid1pxred.com/</link><item><title>Building an API: Rails 3 vs Grape</title><description>&lt;p&gt;I’ve been pretty impressed with the &lt;a href="http://github.com/intridea/grape"&gt;Grape&lt;/a&gt; Rack library for building an API, but I was curious how it stacks up against Rails 3, now that Rails has been Rack-ified and has steadily become more hospitable to APIs.&lt;/p&gt;
&lt;p&gt;Using an existing Rails app with a Grape API mounted as middleware, I ran a benchmark against a vanilla API with this environment:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Grape 0.1.5&lt;/li&gt;
&lt;li&gt;Rails 3.0.10&lt;/li&gt;
&lt;li&gt;Passenger 3.0.5&lt;/li&gt;
&lt;li&gt;Ruby Enterprise Edition (ruby 1.8.7), patchlevel 334&lt;/li&gt;
&lt;li&gt;Macbook Pro, 2.4 GHz / 8GB, OS X 10.6.8&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And it looks like Grape wins in this particular environment:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Grape averages 47.21 req/sec&lt;/li&gt;
&lt;li&gt;Rails 3 averages 31.41  req/sec&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://blog.solid1pxred.com.s3.amazonaws.com/benchmark.png"&gt;&lt;img alt="Grape vs Rails 3 API performance" src="http://blog.solid1pxred.com.s3.amazonaws.com/benchmark.png" width="400"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here’s how I implemented both scenarios:&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1679603.js?file=rails3_vs_grape_apis.rb"&gt;&lt;/script&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/16487806979</link><guid>http://blog.solid1pxred.com/post/16487806979</guid><pubDate>Wed, 25 Jan 2012 18:25:00 -0500</pubDate></item><item><title>Hidden Secrets of the Rails Dev: Gotchas While Migrating from 2 to 3</title><description>&lt;p&gt;Upon migrating from Rails 2 to 3, one might happen across some “gotchas”. I present a few such that you may heed caution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ActiveSupport::Callbacks#run_callbacks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This method takes a &lt;code&gt;&amp;block&lt;/code&gt; parameter. In &lt;a href="http://railsapi.com/doc/rails-v2.3.8/classes/ActiveSupport/Callbacks.html#M003282"&gt;Rails 2&lt;/a&gt;, &lt;code&gt;&amp;block&lt;/code&gt; will run after each callback, and halt the chain if it returns false. In Rails &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html#method-i-run_callbacks"&gt;3&lt;/a&gt;, &lt;code&gt;&amp;block&lt;/code&gt; will run after the &lt;code&gt;:before/:around&lt;/code&gt; callbacks and before the &lt;code&gt;:after&lt;/code&gt; callbacks. More has changed about callbacks, so please read the docs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mail#header&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ActionMailer&lt;/code&gt; in Rails 3 uses a different underlying library than 2: &lt;a href="https://github.com/mikel/mail"&gt;mail&lt;/a&gt; instead of &lt;a href="https://github.com/mikel/tmail"&gt;tmail&lt;/a&gt;. Setting headers in the new library will accumulate headers rather than replacing them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m['X-Something'] = 1
m['X-Something'] = 2
m.header['X-Something'] = 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now m has 3 values for the &lt;code&gt;X-Something&lt;/code&gt; header: 1, 2 and 3.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ActiveRecord::Base#touch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Rails 2, &lt;code&gt;touch()&lt;/code&gt; ultimately calls &lt;code&gt;save!()&lt;/code&gt; and runs through all the validation and callbacks. In Rails 3, &lt;code&gt;touch()&lt;/code&gt; saves the record using &lt;code&gt;update_all()&lt;/code&gt;, so no validations are performed and only the new &lt;code&gt;after_touch()&lt;/code&gt; callback is run.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ActiveRecord#order&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Rails 2, queries are ordered like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.first(:order =&gt; "name")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Rails 3, AREL gives us a new method for queries called order(), but remember that it will accumulate order values instead of replacing them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.order("name").order("id").first
# ... ORDER BY name, id .... #&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember to use &lt;code&gt;reorder()&lt;/code&gt; to reset the value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.order("name").reorder("id")
# ... ORDER BY id ... #&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.solid1pxred.com/post/14585617922</link><guid>http://blog.solid1pxred.com/post/14585617922</guid><pubDate>Wed, 21 Dec 2011 18:24:00 -0500</pubDate></item><item><title>Reorder your Authlogic persistence callbacks</title><description>&lt;p&gt;One thing lacking from ActiveSupport::Callbacks, imo, is a way to reorder callbacks.&lt;/p&gt;
&lt;p&gt;For instance, it would be nice if you could define the order in which Authlogic (which uses ActiveSupport::Callbacks) tries to persist a session (ie ‘remember’ cookie, then ‘session’ cookie, then ‘http_auth’, and so on).&lt;/p&gt;
&lt;p&gt;Here’s some code to put at the end of your session models to prioritize their callback chains…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Rails 2:&lt;/strong&gt;&lt;/p&gt;
&lt;script src="https://gist.github.com/1121054.js"&gt; &lt;/script&gt;&lt;p&gt;&lt;strong&gt;For Rails 3&lt;/strong&gt;:&lt;/p&gt;
&lt;script src="https://gist.github.com/1152224.js"&gt;&lt;/script&gt;&lt;p&gt;(&lt;a href="https://gist.github.com/1121054"&gt;link&lt;/a&gt;)&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/8395134583</link><guid>http://blog.solid1pxred.com/post/8395134583</guid><pubDate>Tue, 02 Aug 2011 15:58:00 -0400</pubDate></item><item><title>"SayIt ☎", a New Pronunciation Tool!</title><description>&lt;p&gt;Have you ever argued with someone over the pronunciation of a word? Let “the cloud” resolve your issue!&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;“SayIt ☎”&lt;/strong&gt;&lt;/span&gt; is my new &lt;a href="http://kynetx.com"&gt;Kynetx&lt;/a&gt;/&lt;a href="http://twilio.com"&gt;Twilio&lt;/a&gt;/&lt;a href="http://forvo.com"&gt;Forvo&lt;/a&gt; mashup that does 1 simple thing: &lt;em&gt;pronounce words&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;Try it… send “plasmometric” to&lt;span&gt; 917.740.1911 … &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;a href="http://sayit.solid1pxred.com/"&gt;&lt;img src="http://solid1pxred.com/say-it/sayit_logo.png"/&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/1720675352</link><guid>http://blog.solid1pxred.com/post/1720675352</guid><pubDate>Sun, 28 Nov 2010 19:43:00 -0500</pubDate></item><item><title>Import your data from RunnersWorld to RunKeeper!</title><description>&lt;p&gt;If you need to move your information from &lt;a href="http://runnersworld.com/"&gt;Runner’s World&lt;/a&gt; into &lt;a href="http://runkeeper.com/"&gt;RunKeeper&lt;/a&gt;, but like me have run into the problem that RunKeeper doesn’t have an api (yet?) and doesn’t let you import data, then fear not!&lt;/p&gt;
&lt;p&gt;If you like living “on the edge”, try running my script by following these steps:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Download the Ruby script &lt;a href="http://github.com/tiegz/RunHacker/raw/master/run_hacker.rb"&gt;here&lt;/a&gt; to any directory&lt;/li&gt;
&lt;li&gt;You’ll have to run a command to get the necessary Ruby libraries: &lt;strong&gt;&lt;code&gt;sudo gem install active_support hpricot json&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://runnersworld.com/log"&gt;Login&lt;/a&gt; to your Training Log at Runner’s World&lt;/li&gt;
&lt;li&gt;Select ‘Tools’&lt;/li&gt;
&lt;li&gt;Select ‘Export’ (in XML format), and click ‘Download’&lt;/li&gt;
&lt;li&gt;Copy the downloaded file into the directory where you saved the Ruby script&lt;/li&gt;
&lt;li&gt;Run this: &lt;strong&gt;&lt;code&gt;ruby run_hacker.rb rwFile.xml &lt;/code&gt;&lt;/strong&gt;(where ‘rwFile.xml’ is the file you downloaded from Runner’s World)&lt;/li&gt;
&lt;li&gt;Finally, you’ll have to enter your RunKeeper email, RunKeeper password, and confirm every event that you would like to import.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;CATCHES: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;For some reason the total distance in RunKeeper is recorded as “0.0” for imported Mapped runs (aka GPS runs). You can fix this by visiting RunKeeper, clicking “Edit Activity” for each Mapped run, move one of the points *very slightly* and then click “Save”. That should reset the distance correctly.&lt;/li&gt;
&lt;li&gt;This should work for RunningAHEAD too, but I haven’t yet figured out how to get the maps from a RunningAHEAD account w/out logging in first.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This script has worked for me so far; let me know if you try it and encounter any problems! I’d love to abstract this into a real api wrapper, but I am on the verge of wasting too much time.&lt;/p&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;
&lt;p&gt;(&lt;a href="http://blog.solid1pxred.com/ask"&gt;comments or bugs?&lt;/a&gt;)&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/627110436</link><guid>http://blog.solid1pxred.com/post/627110436</guid><pubDate>Mon, 24 May 2010 00:17:00 -0400</pubDate></item><item><title>New Name/Site for Kynetx App!!</title><description>&lt;p&gt;I found some tonight to return to &lt;strong&gt;&lt;strike&gt;Similar Stories&lt;/strike&gt; Different Take&lt;/strong&gt; and make a few changes:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;renamed to &lt;strong&gt;Different Take&lt;/strong&gt; (thx Cody)&lt;/li&gt;
&lt;li&gt;added support for &lt;a href="http://www.bloomberg.com/"&gt;Bloomberg News&lt;/a&gt;!!! &lt;/li&gt;
&lt;li&gt;more polishing of the news-search algorithm&lt;/li&gt;
&lt;li&gt;website is now at &lt;a href="http://different-take.com/"&gt;&lt;a href="http://different-take.com"&gt;http://different-take.com&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;added browser extensions (courtesy of &lt;a href="http://www.kynetx.com/"&gt;Kynetx&lt;/a&gt;)… the options for getting your balance of news are:&lt;/li&gt;
&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;Bookmarklet&lt;/li&gt;
&lt;li&gt;Azigo card&lt;/li&gt;
&lt;li&gt;Firefox extension&lt;/li&gt;
&lt;li&gt;Chrome extension&lt;/li&gt;
&lt;li&gt;Internet Explorer extension&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;span&gt; &lt;/span&gt;(visit the &lt;a href="http://different-take.com"&gt;site&lt;/a&gt; to install)&lt;/p&gt;
&lt;p&gt;And if you happen to be in Utah tomorrow (Apr. 27), check out the &lt;a href="http://kynetximpactspring2010.eventbrite.com/"&gt;Kynetx Impact Conference&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://different-take.com"&gt;&lt;img height="30" width="144" alt="Different Take" src="http://different-take.com/different-take.png"/&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/552323916</link><guid>http://blog.solid1pxred.com/post/552323916</guid><pubDate>Mon, 26 Apr 2010 22:47:00 -0400</pubDate></item><item><title>Kynetx App Contest: Similar News Stories</title><description>&lt;p&gt;&lt;b&gt;NAME:&lt;/b&gt; Similar News Stories&lt;/p&gt;
&lt;p&gt;&lt;b&gt;DESCRIPTION&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When the user is on a major news site, this app will attempt to provide up to 20 links to similar news stories from other sources.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;BACKGROUND: &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is a contest entry for the &lt;a href="http://www.kynetx.com/contest/"&gt;Kynetx App Contest&lt;/a&gt;. Go check out &lt;a href="http://www.kynetx.com"&gt;Kynetx&lt;/a&gt; if you haven’t yet— it’s a really nice platform for building context-based applications. Sort of like what hoodwink.d was for commenting, but you can do a lot more than just comments.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;USE CASE&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;User reads a news article; User wants to see how other news sources are reporting the same story; User clicks the “Similar News Stories” bookmarklet and they’re given a list of links to matching news stories.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;WORKING?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is mostly working for me, although I have a few kinks to iron out. The current news sources it is targeted for are: CNN, NYtimes, LATimes, WSJ, DailyKos, FOXNews, Yahoo, Reuters, HuffingtonPost, and MSNBC (I’m having issues with a few of these currently).&lt;/p&gt;
&lt;p&gt;When I have time I’d like to iron out the search algorithm, try to weed out links that point back to the same article, etc.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;HOW TO INSTALL&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;i&gt;Easiest way&lt;/i&gt;: drag this link to your Bookmark Bar and click it whenever you’re on an article: &lt;a href="javascript:(function()%7Bvar%20d=document;var%20s=d.createElement('script');s.text=%22KOBJ_config=%7B'rids':%5B'a218x3'%5D%7D;%22;d.body.appendChild(s);var%20l=d.createElement('script');l.src=%22http://init.kobj.net/js/shared/kobj-static.js%22;d.body.appendChild(l);%7D)()"&gt;Similar News Stories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Have&lt;/i&gt;&lt;i&gt; &lt;a href="http://www.azigo.com"&gt;Azigo&lt;/a&gt;?&lt;/i&gt; try the &lt;a href="http://blog.solid1pxred.com.s3.amazonaws.com/Similar+News+Stories.crd"&gt;‘Similar News Stories’&lt;/a&gt; card.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Browser Extensions?&lt;/i&gt; I haven’t made these yet, but can if you need one!&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;b&gt;EXAMPLE ARTICLES&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Once you’ve installed, &lt;a href="http://www.nytimes.com/2010/02/16/sports/cycling/16landis.html?hpw"&gt;here&lt;/a&gt; is a sample NYTimes article, &lt;a href="http://online.wsj.com/article/SB10001424052748704431404575066652454037516.html"&gt;here’s&lt;/a&gt; one for WSJ, and &lt;a href="http://www.huffingtonpost.com/2010/02/15/evan-bayh-for-president-s_n_463202.html"&gt;here’s&lt;/a&gt; one for HuffingtonPost.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.solid1pxred.com.s3.amazonaws.com/similar_news_stories.png" alt="Sample article used with Similiar News Stories" width="600"/&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/392174116</link><guid>http://blog.solid1pxred.com/post/392174116</guid><pubDate>Tue, 16 Feb 2010 00:06:00 -0500</pubDate></item><item><title>Finally finished my PC festival mashup… and it’s...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_kwquxr6vmp1qzv7tpo1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Finally finished my PC festival mashup… and it’s at &lt;a href="http://pc.muviluv.com/screenings"&gt;pc.muviluv.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It has the screening dates, event dates and venue information for &lt;a href="http://sundance.bside.com/2010/"&gt;Sundance&lt;/a&gt;, &lt;a href="http://slamdance.bside.com/2010/"&gt;Slamdance&lt;/a&gt; and &lt;a href="http://www.x-dance.com/"&gt;X-DANCE&lt;/a&gt; (an “action sports film festival”).&lt;/p&gt;
&lt;p&gt;There are a couple bugs I’d like to fix, but I’m also looking for some feedback for anyone who uses it ^_^&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/350509181</link><guid>http://blog.solid1pxred.com/post/350509181</guid><pubDate>Sun, 24 Jan 2010 04:13:00 -0500</pubDate></item><item><title>Testing ye olde "querystring cache busting" trick.</title><description>&lt;p&gt;When setting your site’s file cache settings, there are 2 common ways to properly save bandwidth with HTTP headers.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;First method: compare the browser cache’s current versions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Set an http header such as &lt;code&gt;ETag&lt;/code&gt; or &lt;code&gt;Last-Modified&lt;/code&gt; that allows a client (browser) to compare its cached version of a file with the one on the server. With &lt;code&gt;ETag&lt;/code&gt;, for example, the client checks the &lt;code&gt;ETag&lt;/code&gt; of its cached file against the server’s version of the file, and a 304 Not Modified is sent back to the client without the actual file contents.&lt;/p&gt;
&lt;p&gt;This method saves bandwidth, but it also requires a &lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;HEAD&lt;/code&gt; request to the server to find out if the browser needs a new version of the file.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Second method: give the file a lifetime in the cache&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;To avoid the lightweight &lt;code&gt;GET&lt;/code&gt;/&lt;code&gt;HEAD&lt;/code&gt; request, we can also set the &lt;code&gt;Expires&lt;/code&gt; or &lt;code&gt;Cache-Control: max-age&lt;/code&gt; headers. Expires will tell the browser the date that the file expires (so it can make a new request to the server), and max-age will tell the browser how long the file is good for (compared to the &lt;code&gt;Date&lt;/code&gt; header returned in the response).&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;b&gt;Cache Busting&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A frequent use of the &lt;code&gt;Expires&lt;/code&gt;/&lt;code&gt;max-age&lt;/code&gt; method is to set a long life (eg 1 year) on all static files (images, css, js, etc.), and then change the url of the file on the page whenever you need to use a newer version of a file (ie “styles_v1.css” to “styles_v2.css”)&lt;/p&gt;
&lt;p&gt;Using querystrings to sidestep the cached file (à la &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html"&gt;Rails&lt;/a&gt;) is a lightweight way (ie “styles.css?MODIFIED_TIME”), but has come under a little &lt;a href="http://carsonified.com/blog/features/webapps/serving-javascript-fast/"&gt;speculation&lt;/a&gt; (namely that the RFC doesn’t allow cacheing files with querystrings &amp; that some browsers won’t allow it).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Test&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;So I took a basic html file and served it over Apache with the following headers on the images, javascript, and stylesheets:&lt;/p&gt;
&lt;p&gt;HTTP/1.1 200 OK &lt;br/&gt;Date: Wed, 18 Nov 2009 20:50:52 GMT &lt;br/&gt;Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8k DAV/2 PHP/5.3.0 Phusion_Passenger/2.2.5 &lt;br/&gt;Accept-Ranges: bytes &lt;br/&gt;Content-Length: XXXX &lt;br/&gt;&lt;b&gt;Expires: Wed, 18 Nov 2019 20:50:52 GMT&lt;/b&gt; &lt;br/&gt;Content-Type: XXXX/XXXX&lt;/p&gt;
&lt;p&gt;(notice that the only caching mechanism is setting the Expires header to 10 years in the future)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Browsers Tested&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Here are the results of testing querystring cache busting on the html file:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Opera 10.01: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;FF3.5: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;FF3.0: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;FF2.0: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;IE8: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;IE7: ???&lt;/li&gt;
&lt;li&gt;IE6: works (ETag/Last-Modified can be set too)&lt;/li&gt;
&lt;li&gt;WebKit r51075: probably works (but ETag/Last-Modified seem to override Expires, so if they are set the Expires is ignored and the freshness check is requested)&lt;/li&gt;
&lt;li&gt;Safari4: probably works (same as Webkit, the ETag/Last-Modified seem to override Expires so they can’t be set)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;b&gt;What the RFC says&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4"&gt;HTTP 1.1 SPEC&lt;sup&gt;&lt;img class="rendericon" src="https://www.limewire.org/jira/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" border="0"/&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/b&gt; &lt;br/&gt;&lt;i&gt;13.9 Side Effects of GET and HEAD&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Unless the origin server explicitly prohibits the caching of their responses, the application of GET and HEAD methods to any resources SHOULD NOT have side effects that would lead to erroneous behavior if these responses are taken from a cache. They MAY still have side effects, but a cache is not required to consider such side effects in its caching decisions. Caches are always expected to observe an origin server’s explicit restrictions on caching.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;We note one exception to this rule: since some applications have traditionally used GETs and HEADs with query URLs (those containing a “?” in the rel_path part) to perform operations with significant side effects, caches MUST NOT treat responses to such URIs as fresh unless the server provides an explicit expiration time. This specifically means that responses from HTTP/1.0 servers for such URIs SHOULD NOT be taken from a cache. See section 9.1.1 for related information.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;This seems a little vague to me, but I interpret as: don’t cache files with querystrings when accepting HTTP/1.0 responses. The good news is that most of use 1.1 these days!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The Conclusion&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;So querystring cachebusting seems to be pretty well supported under the following conditions:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;you’re not serving HTTP/1.0&lt;/li&gt;
&lt;li&gt;you don’t include any cache headers that would require the client to check w/the server for freshness such as &lt;code&gt;Last-Modified&lt;/code&gt; or &lt;code&gt;ETag &lt;/code&gt;(you can do this as a fallback, but the &lt;code&gt;Expires&lt;/code&gt;/&lt;code&gt;max-age&lt;/code&gt; will be useless for Safari/WebKit)&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.solid1pxred.com/post/248906562</link><guid>http://blog.solid1pxred.com/post/248906562</guid><pubDate>Wed, 18 Nov 2009 18:07:00 -0500</pubDate></item><item><title>Logfile art? Yeah I did.</title><description>&lt;p&gt;Here’s a script that takes a filename, parses the file for IP addresses, maps each IP to an RGBA pixel, and creates a PNG (thanks &lt;a href="http://github.com/seattlerb/png"&gt;seattle.rb&lt;/a&gt;!).&lt;/p&gt;
&lt;p&gt;For example, the following would map 192.168.1.1 in reverse (i.e. 1.1.168.192)…&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;b&gt;ruby ip_colorsquare.rb production.log 4,3,2,1&lt;/b&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here’s one example I created with a 24-hour chunk of logs from &lt;a href="http://wherewedowhatwedo.com"&gt;WhereWeDoWhatWeDo&lt;/a&gt; (disclaimer: I mixed up the octet order when I created it)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://solid1pxred.com/images/production.log.png"&gt;&lt;img height="98" width="98" alt="production.log PNG" src="http://solid1pxred.com/images/production.log.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Interesting to see patterns emerge, although the streaks of the same shade are probably just search bots or spammers.&lt;/p&gt;
&lt;p&gt;Grab the script &lt;a href="http://github.com/tiegz/visualization/blob/master/ip_color_square.rb"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/233588421</link><guid>http://blog.solid1pxred.com/post/233588421</guid><pubDate>Wed, 04 Nov 2009 23:54:00 -0500</pubDate><category>wth</category><category>ruby</category><category>logfile</category><category>visualization</category></item><item><title>Troubles with JRuby and SoyLatte on OS X Snow Leopard</title><description>&lt;p&gt;I was trying to install &lt;a href="http://jruby.org/"&gt;JRuby&lt;/a&gt; on a new install of OS X Snow Leopard today, but got this error when trying to run stuff like “jruby -S gem”:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Trace/BPT trap&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I’m using &lt;a href="http://landonf.bikemonkey.org/static/soylatte/"&gt;SoyLatte&lt;/a&gt; for Java development on my machine, and was able to fix the JRuby error by switching back to the Java 1.6 with which Snow Leopard ships.&lt;/p&gt;
&lt;p&gt;So what’s the quick fix — so we don’t have to debug JRuby/SoyLatte — in order to do Java development with SoyLatte, but use JRuby with OSX’s Java 1.6? Add this to the top of your “bin/jruby” file (wherever it lives):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;export JAVA_HOME=/Library/Java/Home&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;やすい!&lt;/b&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/212874091</link><guid>http://blog.solid1pxred.com/post/212874091</guid><pubDate>Wed, 14 Oct 2009 10:14:00 -0400</pubDate></item><item><title>Max Headroom ♥ CSS3</title><description>&lt;a href="http://solid1pxred.com/max_headroom/"&gt;Max Headroom ♥ CSS3&lt;/a&gt;: &lt;p&gt;(latest build of WebKit required)&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/146242375</link><guid>http://blog.solid1pxred.com/post/146242375</guid><pubDate>Tue, 21 Jul 2009 15:11:00 -0400</pubDate></item><item><title>Looking for some +1's to get video_tag() into Rails ^o^</title><description>&lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/2843-patch-add-video_tag-to-actionview#ticket-2843-1"&gt;Looking for some +1's to get video_tag() into Rails ^o^&lt;/a&gt;</description><link>http://blog.solid1pxred.com/post/131321492</link><guid>http://blog.solid1pxred.com/post/131321492</guid><pubDate>Sat, 27 Jun 2009 15:48:43 -0400</pubDate></item><item><title>vijo doesn't overheat my cpu! (yet)</title><description>&lt;p&gt;Here’s what I came up with during the Hack Day portion of the incredible &lt;a href="http://openvideoconference.org/"&gt;Open Video Conference 2009&lt;/a&gt; this weekend. It’s a VJ’ing tool written purely in HTML5 and JS.&lt;/p&gt;
&lt;p&gt;Bear with me if it’s glitchy! It’s just a prototype.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://solid1pxred.com/vijo"&gt;go to vijo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://solid1pxred.com/vijo"&gt;&lt;img src="http://solid1pxred.com/vijo/vijo.png" border="2" width="250"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://solid1pxred.com/vijo"&gt;&lt;br/&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/127895803</link><guid>http://blog.solid1pxred.com/post/127895803</guid><pubDate>Mon, 22 Jun 2009 00:30:00 -0400</pubDate><category>vijo</category><category>javascript sorcery</category><category>html5</category><category>Twitter</category></item><item><title>Deprecating 'www' from Rails Requests with Metal</title><description>&lt;p&gt;In ‘app/metal/deprecate_w_w_w.rb’:&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;pre&gt;# Allow the metal piece to run in isolation
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)

class DeprecateWWW
  def self.call(env)
    if env['HTTP_HOST'].slice!(/^www\./)
      location = "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['REQUEST_URI']}"
      RAILS_DEFAULT_LOGGER.info "DeprecateWWW: Redirecting to #{location}"
      [302, {'Location' =&gt; location}, []]
    else
     # A 400 status (Not Found) passes the call on to the next piece in the stack,
     # which can be another metal piece, or your rails application.
     [404, {"Content-Type" =&gt; "text/html"}, ["Not Found!"]]
   end
  end
end
&lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For example, ‘http://www.solid1pxred.com/foobar’ would be redirected to ‘http://solid1pxred.com/foobar’&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/125417428</link><guid>http://blog.solid1pxred.com/post/125417428</guid><pubDate>Wed, 17 Jun 2009 17:10:00 -0400</pubDate></item><item><title>Radial Gradiant in Safari / Webkit (CSS3)</title><description>&lt;p&gt;Many of the &lt;a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html"&gt;docs&lt;/a&gt; on gradient support in WebKit right now only include examples for “linear” style gradients, while just mentioning the syntax for “radial” styles:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-webkit-gradient(type, inner_center, inner_radius, outer_center, outer_radius, / stop...)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So here’s an example of how to do a “radial” background gradient:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;background: -webkit-gradient(radial, left top, 30, left top, 100, color-stop(0.7, #7C95AC), from(#FFF), to(#304B67));&lt;/code&gt;&lt;/p&gt;
&lt;p style="width: 100px; height: 100px; color: white; background: -webkit-gradient(radial, left top, 30, left top, 100, color-stop(0.7, #7C95AC), from(#FFF), to(#304B67)); line-height: 100px; padding: 10px; margin: 10px;"&gt;And here it is!&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/90407219</link><guid>http://blog.solid1pxred.com/post/90407219</guid><pubDate>Fri, 27 Mar 2009 14:16:16 -0400</pubDate></item><item><title>Keep it shortenTweet</title><description>&lt;p&gt;Behold… &lt;a href="http://shortentweet.com" title="shortenTweet"&gt;shortenTweet&lt;/a&gt;! It’s a wee microapp for &lt;a href="http://twitter.com" title="Twitter"&gt;Twitter&lt;/a&gt; that tries to shorten your tweets using UTF-8, ASCII and some shorthand. It’s a combination of Sinatra + jQuery, and after doing this I’m all aboard this microapp train (esp. with how easy it is to deploy Rack-based apps on Passenger).&lt;/p&gt;
&lt;p&gt;And — par for the course — after I “launched” it, I discovered 2 or 3 or services that already did “tweet shortening” (although I don’t think any of them actually employ UTF-8).&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/83656900</link><guid>http://blog.solid1pxred.com/post/83656900</guid><pubDate>Wed, 04 Mar 2009 22:23:00 -0500</pubDate><category>ruby</category><category>sinatra</category><category>twitter</category></item><item><title>Rails 2.3 : Uninitialized constant CGI::Session</title><description>&lt;p&gt;Upgraded to Rails 2.3 today… very nice, but I ran into this&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uninitialized constant CGI::Session&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To solve, look for anywhere you reference the builtin session stores for rails (ie CookieStore), and change “&lt;code&gt;CGI::Session&lt;/code&gt;” to “&lt;code&gt;ActionController::Session&lt;/code&gt;”. (ie “&lt;code&gt;CGI::Session::CookieStore&lt;/code&gt;” to “&lt;code&gt;ActionController::Session::CookieStore&lt;/code&gt;”)&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/75071082</link><guid>http://blog.solid1pxred.com/post/75071082</guid><pubDate>Mon, 02 Feb 2009 11:57:41 -0500</pubDate></item><item><title>Convention over Configuration'ing my Blog.</title><description>&lt;p&gt;I’m pretty close to ditching my 3-year-old Typo/Joyent shared hosting blog setup soon. I might just replace it with this Tumblelog.&lt;/p&gt;
&lt;p&gt;(apologies to anyone who was following my old blog feed)&lt;/p&gt;</description><link>http://blog.solid1pxred.com/post/71356079</link><guid>http://blog.solid1pxred.com/post/71356079</guid><pubDate>Sun, 18 Jan 2009 12:53:00 -0500</pubDate></item></channel></rss>

