<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Tag rails</title>
    <link>http://blog.moertel.com/articles/tag/rails?tag=rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>A couple of tips for writing Puppet manifests</title>
      <description>&lt;p&gt;I recently started using &lt;a href="http://reductivelabs.com/trac/puppet"&gt;Puppet&lt;/a&gt;
to automate my server-build processes.  The basic idea behind Puppet
is that you create &amp;#8220;manifests&amp;#8221; that declare
a directed graph of &amp;#8220;resources&amp;#8221; that represents the desired state of
your machines.  Puppet-managed machines on your network then query a
master server to obtain the latest copy of the graph, which they then
reconcile with their current states to make whatever changes are
necessary to bring themselves up to date.&lt;/p&gt;


	&lt;p&gt;For the most part, everything works well.  I have encountered a couple
of snags when writing manifests, however, so I&amp;#8217;m going to explain them
here as reminder until I get the time to fix them in the Puppet code and send
patches upstream.&lt;/p&gt;


	&lt;p&gt;First, don&amp;#8217;t use hyphens in class names.  While hyphens are legal
in class names, they are not allowed in qualified variables, thus
variables defined within hyphen-named classes are inaccessible
from the outside world.&lt;/p&gt;


	&lt;p&gt;Second, and this one is both tricky and important, Puppet handles
prerequisites for definitions by silently passing those prerequisites on
to all of the resources within the definitions.  Definitions, in
effect, don&amp;#8217;t really have their own prerequisites, they just pass them on to
their children.  But &amp;#8211; and here&amp;#8217;s the problem &amp;#8211; if those child
resources declare their own prerequisites, those prerequisites will
&lt;em&gt;overwrite the passed-on prerequisites&lt;/em&gt;, effectively causing them to
be ignored.&lt;/p&gt;


	&lt;p&gt;This problem bit me hard when trying to create a definition for
installing Ruby Gems from a local cache of gems:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;define local_gem($gem) {
    $path = "/var/local/local-gems/$gem" 
    file { $path:
        ensure  =&amp;gt; present,
        source  =&amp;gt; "puppet://puppet/files/gems/$gem",
        require =&amp;gt; File["local-gems-dir"],
        owner   =&amp;gt; root,
        group   =&amp;gt; root,
        mode    =&amp;gt; 0664,
    }
    package { $title:
        ensure   =&amp;gt; installed,
        provider =&amp;gt; "gem",
        require  =&amp;gt; [ Package["rubygems"], File[$path] ],
        source   =&amp;gt; $path,
    }
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The intent was to be able to declare a local gem like so:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;local_gem { "sqlite3-ruby":
    gem     =&amp;gt; "sqlite3-ruby-1.2.1.gem",
    require =&amp;gt; Package["sqlite-devel"]
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Thus the &amp;#8220;sqlite3-ruby&amp;#8221; local gem has the single prerequisite of the
&amp;#8220;sqlite-devel&amp;#8221; package &amp;#8211; or at least that&amp;#8217;s what I expected.  What
happened on deployment was that the prerequisite was ignored because
when it was passed on to the inner file and package resources, those
resources had their own &lt;em&gt;require&lt;/em&gt; parameters, and those parameters
overwrote the passed-on prerequisite.&lt;/p&gt;


	&lt;p&gt;The work-around is somewhat hacky.  I augmented the definition with a do-nothing resource
that has no &lt;em&gt;require&lt;/em&gt; parameter of its own.  This
resource does nothing but capture the passed-on prerequisites.  Then I made
all of the other resources in the definition include the do-nothing
resource as one of their prerequisites.  Thus they are made to inherit the
passed-on prerequisites.&lt;/p&gt;


	&lt;p&gt;My final definition looks like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;define local_gem($gem) {

    # dummy exec to propagate requires from local_gem
    exec { $name: command =&amp;gt; "/bin/true" }

    $path = "/var/local/local-gems/$gem" 
    file { $path:
        ensure  =&amp;gt; present,
        source  =&amp;gt; "puppet://puppet/files/gems/$gem",
        require =&amp;gt; [ Exec[$name], File["local-gems-dir"] ],
        owner   =&amp;gt; root,
        group   =&amp;gt; root,
        mode    =&amp;gt; 0664,
    }
    package { $title:
        ensure   =&amp;gt; installed,
        provider =&amp;gt; "gem",
        require  =&amp;gt; [ Exec[$name], Package["rubygems"], File[$path] ],
        source   =&amp;gt; $path,
    }
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Notice how the file and package resource both require the dummy exec resource.
That&amp;#8217;s the trick that allows them to require the prerequisites passed on from
the local_gem definition.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s not pretty, but it works.  &lt;a href="http://mail.madstop.com/pipermail/puppet-users/2007-March/001953.html"&gt;See this email on the puppet-users mailing list&lt;/a&gt; for more on the problem.&lt;/p&gt;</description>
      <pubDate>Thu, 15 Nov 2007 02:30:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:4fc6dc28-ae38-4d72-ac05-d9a65d6653f8</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/11/15/a-couple-of-tips-for-writing-puppet-manifests</link>
      <category>sysadmin</category>
      <category>rails</category>
      <category>puppet</category>
      <category>manifests</category>
      <category>gems</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/622</trackback:ping>
    </item>
    <item>
      <title>I have written a short novel's worth of content for my blog</title>
      <description>&lt;p&gt;How much content have I written for my blog?  Let&amp;#8217;s find out.&lt;/p&gt;


	&lt;p&gt;My blog runs on &lt;a href="http://typosphere.org/"&gt;Typo&lt;/a&gt;, which is built upon
&lt;a href="http://www.rubyonrails.com/"&gt;Ruby on Rails&lt;/a&gt;.  Let&amp;#8217;s fire up the Rails
console and gather a quick word count:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="global"&gt;$ &lt;/span&gt;&lt;span class="ident"&gt;cd&lt;/span&gt; ~&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;blog&lt;/span&gt;
&lt;span class="global"&gt;$ &lt;/span&gt;&lt;span class="ident"&gt;ruby&lt;/span&gt; &lt;span class="ident"&gt;script&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;console&lt;/span&gt; 
&lt;span class="constant"&gt;Loading&lt;/span&gt; &lt;span class="ident"&gt;development&lt;/span&gt; &lt;span class="ident"&gt;environment&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;sum&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;sum&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt;
       &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;body&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;extended&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;(/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\s&lt;/span&gt;+&lt;/span&gt;&lt;span class="punct"&gt;/).&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;66665&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So I have written about 66 kilo-words, which is entering &lt;a href="http://en.wikipedia.org/wiki/Novel"&gt;novel
territory&lt;/a&gt;.  Paperback-wise,
it&amp;#8217;s about 190 pages.&lt;/p&gt;


	&lt;p&gt;All I need now is a villain and some cool cover art.&lt;/p&gt;


&lt;code&gt;;-)&lt;/code&gt;</description>
      <pubDate>Fri, 30 Mar 2007 00:34:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:7f3fdbe1-3f38-4322-b8d2-0ab67f887114</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/03/30/i-have-written-a-short-novels-worth-of-content-for-my-blog</link>
      <category>site news</category>
      <category>rails</category>
      <category>writing</category>
      <category>rails</category>
      <category>writing</category>
      <category>words</category>
      <category>word_count</category>
      <category>blog</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/426</trackback:ping>
    </item>
    <item>
      <title>Ruby 1.9 gets handy new method Object#tap</title>
      <description>&lt;p&gt;Via
&lt;a href="http://eigenclass.org/hiki.rb?Changes-in-Ruby-1.9-update-6"&gt;eigenclass.org&lt;/a&gt;
I learned that Ruby 1.9 will sport a new &lt;code&gt;Object&lt;/code&gt; method
called
&lt;a href="http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l25"&gt;&lt;code&gt;tap&lt;/code&gt;&lt;/a&gt;,
which is something I&amp;#8217;ve been &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/189541"&gt;hoping
for&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;What&amp;#8217;s &lt;code&gt;tap&lt;/code&gt;?  It&amp;#8217;s a helper for call chaining.  It
passes its object into the given block and, after the block finishes,
returns the object:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;an_object&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;tap&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;o&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="comment"&gt;# do stuff with an_object, which is in o&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt; &lt;span class="comment"&gt;# ===&amp;gt; an_object&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The benefit is that &lt;code&gt;tap&lt;/code&gt; always returns the object it&amp;#8217;s called on, even if the block returns some other result.  Thus you can insert a &lt;code&gt;tap&lt;/code&gt; block into the middle of an existing method pipleline without breaking the flow.  MenTaLguY has some &lt;a href="http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions"&gt;nifty examples&lt;/a&gt; of other things you can do with &lt;code&gt;tap&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Fans of Ruby on Rails may recognize &lt;code&gt;tap&lt;/code&gt; as similar to RoR&amp;#8217;s own
&lt;a href="http://weblog.jamisbuck.org/2006/10/27/mining-activesupport-object-returning"&gt;&lt;code&gt;returning&lt;/code&gt;&lt;/a&gt; helper.&lt;/p&gt;


	&lt;p&gt;Looks like Ruby 1.9 is going to be extra cool for a number of reasons.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Feb 2007 12:08:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:9a2e5bfe-f2b1-462f-88c5-cd231503292a</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/02/07/ruby-1-9-gets-handy-new-method-object-tap</link>
      <category>ruby</category>
      <category>rails</category>
      <category>ruby</category>
      <category>rails</category>
      <category>tap</category>
      <category>helpers</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/362</trackback:ping>
    </item>
    <item>
      <title>If unit testing can't keep Rails safe from string-escaping problems, what makes you think it will keep your projects safe?</title>
      <description>&lt;p&gt;Recently I wrote about &lt;a href="http://blog.moertel.com/articles/2006/10/10/unit-testing-is-a-tool-not-a-goal"&gt;unit testing being a tool, not a goal in
itself&lt;/a&gt;.
I argued that unit testing was not a reliable way to fight
certain kinds of common coding errors and, therefore, that unit testing
ought to be supplemented with other tools.&lt;/p&gt;


	&lt;p&gt;To support my argument, I gave an example of a common, important
coding error that unit testing does a bad job of helping programmers
control.  That error is failing to manage and escape strings
properly: the &amp;#8220;strings problem.&amp;#8221;  It is the mother of &lt;span class="caps"&gt;XSS&lt;/span&gt; and
&lt;span class="caps"&gt;SQL&lt;/span&gt;-injection security vulnerabilities, not to mention the cause of
legions of broken links and bad &lt;span class="caps"&gt;HTML&lt;/span&gt; on the web.&lt;/p&gt;


	&lt;p&gt;If you think I&amp;#8217;m overstating the problem, or if you think that unit
testing is a good way of solving it, let me show you how easy it is
for even smart developers to get it wrong.&lt;/p&gt;


	&lt;p&gt;Consider &lt;a href="http://rubyonrails.com/"&gt;Ruby on
Rails&lt;/a&gt;, a great framework
for developing web applications.
Rails has an extensive suite of unit tests, and the &lt;a href="http://dev.rubyonrails.org/"&gt;Rails development guidelines&lt;/a&gt; require that changes to Rails be accompanied by unit tests that &amp;#8220;prove [the] change works.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Now consider that one of Rails&amp;#8217;s most-used and &lt;a href="http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails"&gt;most-scrutinized&lt;/a&gt; methods &amp;#8211; the venerable &lt;code&gt;link_to&lt;/code&gt; helper &amp;#8211; contains a fundamental string-escaping error:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;require 'rubygems'
require_gem 'rails'
include ActionView::Helpers::UrlHelper

url = "http://example.com?ohms_law?volt=1&amp;#38;amp=3" 
puts link_to("TEST", url)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The code, when executed, prints the following &lt;span class="caps"&gt;HTML&lt;/span&gt; snippet:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;a href="http://example.com?ohms_law?volt=1&amp;#38;amp=3"&amp;gt;TEST&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The &lt;span class="caps"&gt;HTML&lt;/span&gt; snippet represents a hypertext link.  The link should point
to the &lt;span class="caps"&gt;URL&lt;/span&gt; given in the code, but because the &lt;span class="caps"&gt;URL&lt;/span&gt; was not properly
escaped when it was converted into &lt;span class="caps"&gt;HTML&lt;/span&gt; by the &lt;code&gt;link_to&lt;/code&gt; helper, the
link is broken:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;CORRECT:  http://example.com?ohms_law?volt=1&amp;#38;amp=3
LINK_TO:  http://example.com?ohms_law?volt=1&amp;#38;=3
                                             ^ oops
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Here&amp;#8217;s what&amp;#8217;s going on.  Because the &lt;span class="caps"&gt;URL&lt;/span&gt; was not escaped, web browsers
misinterpret its &amp;#8220;amp&amp;#8221; parameter as a character-entity reference,
which gets gobbled up when the link&amp;#8217;s &lt;code&gt;href&lt;/code&gt; attribute is parsed.
(To see this for yourself, save the output of the Ruby code into an
&lt;span class="caps"&gt;HTML&lt;/span&gt; file, open the file with your favorite web browser, and see where
the link points.)&lt;/p&gt;


	&lt;p&gt;Now, how come the unit tests didn&amp;#8217;t catch this problem?
It turns out, the tests got it wrong, too, by expecting
broken output:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# in url_helper_test.rb

def test_link_tag_with_query
  assert_dom_equal \
    "&amp;lt;a href=\"http://www.example.com?q1=v1&amp;amp;amp;q2=v2\"&amp;gt;Hello&amp;lt;/a&amp;gt;",
    link_to("Hello", "http://www.example.com?q1=v1&amp;amp;amp;q2=v2")
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The point isn&amp;#8217;t that the Rails developers are dumb.  The point is that
the Rails developers are smart.  If &lt;em&gt;they&lt;/em&gt; can&amp;#8217;t get the strings
problem right, even with all their brains and all their unit testing,
what reason does &lt;em&gt;any&lt;/em&gt; programmer have to think that unit testing is going
to solve this problem reliably?&lt;/p&gt;


	&lt;p&gt;If, then, you want to solve the strings problem &amp;#8211; and you really,
seriously &lt;em&gt;ought&lt;/em&gt; to want to solve the strings problem &amp;#8211; you should
consider options beyond unit testing.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update 2007-09-04:&lt;/strong&gt; I just noticed that the documentation for
&lt;em&gt;link_to&lt;/em&gt; has been revised to state that if you pass a
string as its &lt;em&gt;options&lt;/em&gt; parameter, the string will be interpreted not
as a &lt;span class="caps"&gt;URL&lt;/span&gt; but as an &lt;span class="caps"&gt;HTML&lt;/span&gt; &lt;em&gt;href&lt;/em&gt; attribute value, that is, an
&lt;span class="caps"&gt;HTML&lt;/span&gt;-encoded &lt;span class="caps"&gt;URL&lt;/span&gt;.  The old documentation:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt; &lt;code&gt;def link_to(name, options = {}, html_options = nil, *parms)&lt;/code&gt;&lt;br/&gt;Creates a link tag of
the given &lt;em&gt;name&lt;/em&gt; using an &lt;span class="caps"&gt;URL&lt;/span&gt; created by the set of &lt;em&gt;options&lt;/em&gt;.... It&amp;#8217;s
also possible to pass a string instead of an options hash to get a
link tag that just points without consideration.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;The relevant part of the revised documentation:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;It&amp;#8217;s also possible to pass a string instead of an options hash to
get a link tag that uses the value of the string as the href for the
link.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;So, according to the updated documentation, the test I described in my
article is actually correct.  Does this mean that string-handling code
is Rails is worry free?  The existence of helper methods like &lt;a href="http://dev.rubyonrails.org/changeset/5321"&gt;&lt;em&gt;fix_double_escape&lt;/em&gt;&lt;/a&gt;
suggests the answer is no.&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Thu, 12 Oct 2006 16:06:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:03f6d26c-1207-4022-a970-b80231721ea6</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/10/12/if-unit-testing-cant-keep-rails-safe-from-string-escaping-problems-what-makes-you-think-it-will-keep-your-projects-safe</link>
      <category>programming</category>
      <category>testing</category>
      <category>rails</category>
      <category>rails</category>
      <category>testing</category>
      <category>strings</category>
      <category>problem</category>
      <category>escaping</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/184</trackback:ping>
    </item>
    <item>
      <title>Database connection leak in Typo 4.0.3: problem solved</title>
      <description>&lt;p&gt;In &lt;a href="http://blog.moertel.com/articles/2006/08/24/typo-4-0-3-instability-and-a-minor-patch-for-sqlite3-ruby"&gt;an earlier post&lt;/a&gt; I wrote about stability
problems that have plagued my blog since upgrading from &lt;a href="http://typosphere.org"&gt;Typo&lt;/a&gt; 4.0.0 to 4.0.3.  I have finally traced the problem to its source, and here&amp;#8217;s the deal:&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;If you&amp;#8217;re serving Typo up via &lt;a href="http://mongrel.rubyforge.org/index.html"&gt;Mongrel&lt;/a&gt;, do not configure ActiveRecord to allow concurrency.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;One of the changes between Typo 4.0.0 and 4.0.3 is this
addition to the &lt;code&gt;environment.rb&lt;/code&gt; file:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;config.active_record.allow_concurrency = true
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;del&gt;Comment out this line, restart Typo, and the problem is solved.&lt;/del&gt;
Apply Changeset 1255, and the problem is solved.  (See
&lt;a href="#article165-update2"&gt;Update 2&lt;/a&gt;, below.)&lt;/p&gt;


	&lt;h3&gt;Discussion&lt;/h3&gt;


&lt;p&gt;When &lt;code&gt;ActiveRecord::Base.allow_concurrency&lt;/code&gt; is set to
&lt;code&gt;true&lt;/code&gt;, AR will give each thread its own database
connections and cache them in thread-localized storage.  The idea is
that, in a multi-threaded environment, this simple policy prevents
unsafe interactions between threads and the database.  (Imagine what
would happen if one thread &amp;#8220;borrowed&amp;#8221; a connection over which
another thread had opened a transaction.  Oops, there goes
transactional isolation.)&lt;/p&gt;

	&lt;p&gt;This policy, however, does place a burden on the owner of the threads to
make sure that each thread&amp;#8217;s local connection cache is cleared when
the thread is joined, a burden that is not, it would seem, being
carried by Typo under Mongrel.  As a result, Typo rapidly chews
through the allotment of file descriptors that the operating system
kindly had reserved for Mongrel:&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/pix/20060824/blog-fd-usage-vs-time.png" title="Typo 4.0.3 on Mongrel w/ SQLite3 consumes about 1.7 file descriptors per minute when ActiveRecord is configured to allow concurrency" alt="Typo 4.0.3 on Mongrel w/ SQLite3 consumes about 1.7 file descriptors per minute when ActiveRecord is configured to allow concurrency" /&gt;&lt;/p&gt;


	&lt;p&gt;(On my Linux server, the Mongrel process gets an allotment of 1024
file descriptors.)&lt;/p&gt;


	&lt;p&gt;Lucky for us, this each-thread-gets-its-own-connections policy is unnecessary under
Mongrel because Mongrel, while being multi-threaded itself, serializes
all access to the Rails-based applications it serves up:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Q: Is [Mongrel] multi-threaded or can it handle concurrent requests?&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;Mongrel is uses a pool of thread workers to do it&amp;#8217;s processing. This means that it is able to handle concurrent access and should be thread safe. This also means that you have to be more careful about how you use Mongrel. You can&amp;#8217;t just write your application assuming that there are no threads involved. ...&lt;/p&gt;


	&lt;p&gt;Ruby on Rails is not thread safe so there is a synchronized block around the calls to Dispatcher.dispatch. This means that everything is threaded right before and right after Rails runs. While Rails is running there is only one controller in operation at a time.&lt;/p&gt;


(Source: &lt;a href="http://mongrel.rubyforge.org/faq.html"&gt;Mongrel &lt;span class="caps"&gt;FAQ&lt;/span&gt; list&lt;/a&gt;)
&lt;/blockquote&gt;

Thus we can safely turn off (i.e., comment out in Typo&amp;#8217;s
&lt;code&gt;environment.rb&lt;/code&gt; file) ActiveRecord&amp;#8217;s allow-currency option
without having to worry about nasty concurrency or performance issues:

&lt;pre&gt;&lt;code&gt;# the following line is commented out
# config.active_record.allow_concurrency = true
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;For more on this subject, see &lt;a href="http://dev.rubyonrails.org/ticket/2162"&gt;Rails ticket
#2162&lt;/a&gt; and &lt;a href="http://dev.rubyonrails.org/ticket/2742"&gt;Rails ticket
#2742&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Now, here&amp;#8217;s my question: Are there any environments in which
Typo can run with the allow-concurrency option enabled and &lt;em&gt;not&lt;/em&gt;
leak database connections?  Inquiring minds want to know.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Upon further investigation, turning off
concurrency might not be altogether without risk.  Some of the Typo
code that handles potentially long tasks, such as making trackbacks
and pings, spawns new threads in which to carry out its work.  I&amp;#8217;m
looking further into this risk.  Updates to come.&lt;/p&gt;


&lt;p id="article165-update2"&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; Piers Cawley added &lt;a href="http://www.typosphere.org/trac/changeset/1255"&gt;Changeset
1255&lt;/a&gt;, which turns AR&amp;#8217;s
allow-concurrency flag back off and revises the ping code so that
it does not attempt concurrent database access.  Apply &lt;a href="http://www.typosphere.org/trac/changeset/1255?format=diff&amp;#38;new=1255"&gt;the patch version of
1255&lt;/a&gt;
and restart Typo to get the fix.  A tip of the hat to Piers for making
the quick fix when he was supposed to be on holiday.&lt;/p&gt;

&lt;/div&gt;</description>
      <pubDate>Thu, 24 Aug 2006 15:41:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:ef03f59b-8bc4-4744-b94d-2966da53dca2</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/08/24/database-connection-leak-in-typo-4-0-3-problem-solved</link>
      <category>ruby</category>
      <category>typo</category>
      <category>rails</category>
      <category>typo</category>
      <category>sqlite3</category>
      <category>rails</category>
      <category>activerecord</category>
      <category>concurrency</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/165</trackback:ping>
    </item>
    <item>
      <title>Typo-4.0.3 instability and a minor patch for sqlite3-ruby</title>
      <description>&lt;p&gt;Since I upgraded my blog from &lt;a href="http://typosphere.org/"&gt;Typo&lt;/a&gt; 4.0.0 to
4.0.3, it has been somewhat unstable.  About once a day it starts
responding with &amp;#8220;500 Internal Server Error&amp;#8221; and stays that way until I
restart it.&lt;/p&gt;


	&lt;p&gt;The root of the problem seems to be the database
connection, as evidenced by this exception showing up in the
production log:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;SQLite3::CantOpenException (could not open database)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Unfortunately, the exception doesn&amp;#8217;t provide anything specific
to go on.&lt;/p&gt;


	&lt;p&gt;A quick look at the
&lt;a href="http://rubyforge.org/projects/sqlite-ruby/"&gt;sqlite3-ruby&lt;/a&gt; code
suggested that I was not going to get the specifics, either.  The Ruby-based wrapper
never calls &lt;a href="http://www.sqlite.org/capi3ref.html#sqlite3_errmsg"&gt;sqlite3_errmsg&lt;/a&gt; after a call to &lt;a href="http://www.sqlite.org/capi3ref.html#sqlite3_open"&gt;sqlite3_open&lt;/a&gt; fails on behalf of SQLite3::Database.new.&lt;/p&gt;


	&lt;p&gt;A quick patch, however, fixed the problem:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;--- sqlite3-ruby-1.1.0.orig/lib/sqlite3/database.rb
+++ sqlite3-ruby-1.1.0/lib/sqlite3/database.rb
@@ -109,7 +109,7 @@
       @statement_factory = options[:statement_factory] || Statement

       result, @handle = @driver.open( file_name, utf16 )
-      Error.check( result, nil, "could not open database" )
+      Error.check( result, self, "could not open database" )

       @closed = false
       @results_as_hash = options.fetch(:results_as_hash,false)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;(Submitted as &lt;a href="http://rubyforge.org/tracker/index.php?func=detail&amp;#38;aid=5504&amp;#38;group_id=254&amp;#38;atid=1043"&gt;Ticket 5504&lt;/a&gt; on &lt;a href="http://rubyforge.org/"&gt;RubyForge&lt;/a&gt;.)&lt;/p&gt;


	&lt;p&gt;Before applying the patch, opening a database at a nonexistent path results in
a generic error message:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ ruby -r rubygems -e 'require_gem "sqlite3-ruby";
    SQLite3::Database.new("/no/such/path/db")'

&lt;/code&gt;... could not open database (SQLite3::CantOpenException) ...
&lt;/pre&gt;

	&lt;p&gt;After applying the patch, we get additional error information:&lt;/p&gt;


&lt;pre&gt;... could not open database: unable to open database file
    (SQLite3::CantOpenException) ...
&lt;/pre&gt;

	&lt;p&gt;With the patch in place, all I have to do is wait for Typo to start
acting up again.  Then I&amp;#8217;ll have some interesting information in the
log.&lt;/p&gt;


	&lt;p&gt;Until then, I&amp;#8217;m relying on &lt;a href="http://en.wikipedia.org/wiki/Crontab"&gt;cron&lt;/a&gt;
and a short monitoring script to restart Typo when it tips into
foolishness:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#!/bin/bash

url=http://blog.moertel.com/admin
addrs=tom@moertel.com

response=$(GET -sd $url 2&amp;gt;&amp;#38;1)

if [ "$response" != "200 OK" ]; then
    { echo "Response was: $response"; echo; service typo restart; } |
    mail -s "Blog site not responding! (Restarting)" $addrs
fi
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We&amp;#8217;ll see how it goes.&lt;/p&gt;


&lt;div class="update"&gt; &lt;strong&gt;Update:&lt;/strong&gt; That was fast.  The error popped up
again and this time the log told me something useful: &amp;#8220;unable to open
database file.&amp;#8221;  Now, why couldn&amp;#8217;t Typo open the database file,
especially since the file is perfectly fine and had been opened
successfully (many times) by the very same Typo process earlier?  Here&amp;#8217;s
a hint:

&lt;pre&gt;&lt;code&gt;$ ls /proc/28788/fd | wc -l
&lt;/code&gt;1023
&lt;/pre&gt;

	&lt;p&gt;Seems like there&amp;#8217;s a resource leak in Typo 4.0.3 (or Rails 1.1.6).
Under some conditions, instead of reusing existing database
connections, Typo keeps trying to open new ones.  Eventually, it uses
up its allotment of file descriptors and the operating system is forced
to say, &amp;#8220;That&amp;#8217;s enough, pal,&amp;#8221; (&lt;a href="http://www.wlug.org.nz/EMFILE"&gt;&lt;code&gt;EMFILE&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll look in to it more in the morning.&lt;/p&gt;


&lt;strong&gt;Update 2:&lt;/strong&gt; &lt;a href="http://blog.moertel.com/articles/2006/08/24/database-connection-leak-in-typo-4-0-3-problem-solved"&gt;Problem solved&lt;/a&gt;.
&lt;/div&gt;</description>
      <pubDate>Thu, 24 Aug 2006 00:41:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:2e527a1f-3415-4322-9f0f-244b45a3b695</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/08/24/typo-4-0-3-instability-and-a-minor-patch-for-sqlite3-ruby</link>
      <category>ruby</category>
      <category>typo</category>
      <category>rails</category>
      <category>sysadmin</category>
      <category>typo</category>
      <category>sqlite3</category>
      <category>rails</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/163</trackback:ping>
    </item>
    <item>
      <title>Google Web Accelerator vs. unsafe linking: Round Two!</title>
      <description>&lt;p&gt;The good folks at &lt;a href="http://37signals.com"&gt;37signals&lt;/a&gt; are once again up
in arms about &lt;a href="http://webaccelerator.google.com/"&gt;Google Web
Accelerator&lt;/a&gt; (GWA).  David
Heinemeier Hansson (DHH), in particular, writes in a recent post to
&lt;a href="http://37signals.com/svn/"&gt;Signal vs. Noise&lt;/a&gt; that &amp;#8220;[GWA] was evil
enough the first time around, but this time it&amp;#8217;s downright scary.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The problem, it seems, is that &lt;span class="caps"&gt;GWA&lt;/span&gt; automatically, silently, and
unblockably follows hypertext links to web pages that are linked to by
the pages you visit.  It does this in order to cache those pages so
that if you visit them later, it will have cached copies ready in an
instant, thus &amp;#8220;accelerating&amp;#8221; your web surfing.  But some web
developers use hypertext links to trigger potentially unsafe actions,
such as deleting records in a database, and when &lt;span class="caps"&gt;GWA&lt;/span&gt; automatically
follows such links, it triggers the actions.&lt;/p&gt;


	&lt;p&gt;Oops.&lt;/p&gt;


	&lt;h3&gt;Let&amp;#8217;s do the time warp again&amp;#8230;&lt;/h3&gt;


	&lt;p&gt;Now, if this story sounds familiar, that&amp;#8217;s because half a year
ago, the exact same thing happened.  &lt;span class="caps"&gt;GWA&lt;/span&gt; was unveiled to the public.
People started using it.  And some of those people started losing data
from their accounts with popular web applications, such as
37signal&amp;#8217;s own &lt;a href="http://www.backpackit.com/"&gt;Backpack&lt;/a&gt;.  37signals
&lt;a href="http://37signals.com/svn/archives2/google_web_accelerator_hey_not_so_fast_an_alert_for_web_app_designers.php"&gt;publicized the problem in their blog&lt;/a&gt; and &lt;span class="caps"&gt;DHH&lt;/span&gt; even
&lt;a href="http://www.loudthinking.com/arc/000454.html"&gt;called for a recall on &lt;span class="caps"&gt;GWA&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;And then the community responses came in.  For the most part, the
responses could be divided into two camps, based on who was
blamed for the problem. The first camp blamed the web designers who used
links to trigger unsafe actions (in violation of applicable standards),
and the second camp blamed Google for unleashing &lt;span class="caps"&gt;GWA&lt;/span&gt; upon a web where
standards aren&amp;#8217;t always followed.&lt;/p&gt;


	&lt;p&gt;Both viewpoints had some merit, but I was in the first camp and thus
argued for following the standards and against unsafe linking
practices:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://community.moertel.com/ss/space/start/2005-05-06/1#Google_Web_Accelerator_offers_web_developers_an_important_opportunity"&gt;Google Web Accelerator offers web developers an important opportunity&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://community.moertel.com/ss/space/start/2005-05-08/1"&gt;Taking the unsafe GETs out of Rails&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;What surprised me was that so many people in the second camp argued in
defense of unsafe linking practices, which I had thought indefensible.
I didn&amp;#8217;t have any problem with arguments against Google&amp;#8217;s unleashing
&lt;span class="caps"&gt;GWA&lt;/span&gt; on an imperfect web, but arguing &lt;em&gt;for&lt;/em&gt; the web&amp;#8217;s imperfections
seemed like an odd way of making the case.  The supportive arguments
boiled down to the following:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Lots of web sites use action-triggering links, so the practice is &lt;em&gt;de facto&lt;/em&gt; acceptable.&lt;/li&gt;
		&lt;li&gt;The existing palette of user-interface options is too limited for today&amp;#8217;s web applications; thus, designers are justified in breaking the rules.&lt;/li&gt;
		&lt;li&gt;The standards don&amp;#8217;t actually prohibit the practice (they say &amp;#8220;SHOULD &lt;span class="caps"&gt;NOT&lt;/span&gt;,&amp;#8221; not &amp;#8220;MUST &lt;span class="caps"&gt;NOT&lt;/span&gt;&amp;#8221;); thus, the practice is allowable.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;None of the arguments seem to withstand scrutiny.  The first argument
breaks down like so: That lots of web sites do it only means that
those sites get away with it, not that the practice is acceptable.
Further, as &lt;span class="caps"&gt;GWA&lt;/span&gt; demonstrates, those sites may not get away with the
practice much longer.&lt;/p&gt;


	&lt;p&gt;The second argument breaks down when one examines the uses of unsafe
linking practices.  Most of them could be replaced by safe practices
through modest UI refactoring.  Given that safe alternatives exist,
the unsafe practices are not justified by virtue of being the only realistic option.&lt;/p&gt;


	&lt;p&gt;The third argument breaks down when one actually reads the relevant
standards.  Then it becomes clear that one should not use links to
trigger potentially unsafe actions.  The wiggle room created
by the use of &amp;#8220;SHOULD &lt;span class="caps"&gt;NOT&lt;/span&gt;&amp;#8221; instead of &amp;#8220;MUST &lt;span class="caps"&gt;NOT&lt;/span&gt;&amp;#8221; does not admit 
the large problems caused by unsafe linking.&lt;/p&gt;


	&lt;p&gt;Finally, even if there were some justification for unsafe linking, the
practice would still be a bad idea: its costs and risks outweigh its
benefits.  Why hold back the potential of efficient caching
architectures for the web?  Why risk data loss for your users?  It&amp;#8217;s
not worth it.&lt;/p&gt;


	&lt;h3&gt;Back to the Future&lt;/h3&gt;


	&lt;p&gt;So where are we now?  Given how little justification there is for
unsafe linking practices, one would hope that we would have abandoned
them by now.  But, as the recent cries about the second coming of &lt;span class="caps"&gt;GWA&lt;/span&gt;
suggest, the web-development community is not yet ready to give up those
sexy, action-triggering links.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s not that the means aren&amp;#8217;t available.  Rails, for example, has
plenty of support for sane and safe practices for triggering actions.
Rather, the problem is cultural.  Too many influential people,
especially in the Rails community, are unrepentant users of &amp;#8211; and, dare
I say it, apologists for &amp;#8211; action-triggering links.  Until this changes, I
expect many new web developers to pick up dangerous habits from the
very people they respect most.&lt;/p&gt;


	&lt;p&gt;Fortunately, many other respect-worthy people are pointing toward
a better way:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.intertwingly.net/blog/2005/10/24/Theyre-baaaaaaack"&gt;Sam Ruby&lt;/a&gt;: &amp;#8220;I&amp;#8217;m on the other side of this debate. While this appears to be a purely philosophical concern, in reality this stuff matters.&amp;#8221; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.dehora.net/journal/2005/10/hey_im_back.html"&gt;Bill de hÓra&lt;/a&gt;: &amp;#8220;The &lt;span class="caps"&gt;GWA&lt;/span&gt; is back and following &lt;span class="caps"&gt;GET&lt;/span&gt; links again&amp;#8230; The technology itself is interesting insofar as we are going to see more and more highly automated robots enter the web over the next few years&amp;#8230;. Even more interesting is the kind of outrage holding forth in places like Signal v Noise&amp;#8230;.&amp;#8221; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://bitworking.org/news/Five_months_later_and_web_standards_still_matter"&gt;Joe Gregorio&lt;/a&gt; : &amp;#8220;And now we begin the next chapter in which Pooh discovers that five months after the first time Google turned on &lt;span class="caps"&gt;GWA&lt;/span&gt; that standards still matter.&amp;#8221;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I hope that this time around the web-development community answers
the wake-up call.  It&amp;#8217;s time to abandon action-triggering links.&lt;/p&gt;</description>
      <pubDate>Tue, 25 Oct 2005 16:12:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:23f7ff724af7f0e12fe123ff3e7362ab</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/10/25/google-web-accelerator-vs-unsafe-linking-round-two</link>
      <category>web development</category>
      <category>rails</category>
      <category>rest</category>
      <category>get</category>
      <category>gwa</category>
      <category>safe</category>
      <category>unsafe</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/8</trackback:ping>
    </item>
    <item>
      <title>The button_to helper is now part of Rails!</title>
      <description>&lt;p&gt;I am delighted to report that the &lt;a href="http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails"&gt;button_to
helper&lt;/a&gt;
has been added to the &lt;a href="http://www.rubyonrails.com/"&gt;Ruby on Rails&lt;/a&gt;
web-development framework.  &lt;a href="http://www.loudthinking.com/"&gt;David&lt;/a&gt;
applied &lt;a href="http://dev.rubyonrails.org/changeset/1437"&gt;the patch&lt;/a&gt; earlier
today, and so &lt;em&gt;button_to&lt;/em&gt; will be in the much-anticipated Rails 1.0
release.&lt;/p&gt;


	&lt;p&gt;David&amp;#8217;s change-log entry summarizes the patch well:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Added &lt;em&gt;button_to&lt;/em&gt; as a form-based solution to deal with harmful
actions that should be hidden behind POSTs. This makes it just as
easy as &lt;em&gt;link_to&lt;/em&gt; to create a safe trigger for actions like destroy,
although it&amp;#8217;s limited by being a block element, the fixed look,
and a no-no inside other forms.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;David does a good job of highlighting the helper&amp;#8217;s limitations. I&amp;#8217;ll
take this opportunity to elaborate on each.&lt;/p&gt;


	&lt;h3&gt;It is a block element&lt;/h3&gt;


	&lt;p&gt;The &lt;em&gt;button_to&lt;/em&gt; helper creates a small form, which in &lt;span class="caps"&gt;HTML&lt;/span&gt; is considered
&lt;a href="http://www.w3.org/TR/html4/sgml/dtd.html#block"&gt;block content&lt;/a&gt;, just
like the &lt;em&gt;p&lt;/em&gt;, &lt;em&gt;div&lt;/em&gt;, and &lt;em&gt;blockquote&lt;/em&gt; elements are. Basically, block
content cannot be mixed into runs of text. But links can: links are
&lt;a href="http://www.w3.org/TR/html4/sgml/dtd.html#inline"&gt;inline content&lt;/a&gt;. Thus
&lt;em&gt;button_to&lt;/em&gt; cannot be used as a drop-in replacement for every
occurrence of &lt;em&gt;link_to&lt;/em&gt; that might be unsafe; it works only for those
occurrences within block-accepting contexts.&lt;/p&gt;


	&lt;p&gt;Luckily for us, when designers use links to trigger unsafe actions,
they rarely slip such links into the middle of ordinary looking
text. Naughty uses of &lt;em&gt;link_to&lt;/em&gt; almost always occur within contexts
that accept block content. In Rails-generated scaffolding code, for
instance, the unsafe uses of &lt;em&gt;link_to&lt;/em&gt; occur within table cells, and
table cells have a &lt;a href="http://www.w3.org/TR/html4/sgml/dtd.html#flow"&gt;flow content
model&lt;/a&gt;, which accepts
both inline and block content. So &lt;em&gt;button_to&lt;/em&gt; works great for the
default cases in Rails.&lt;/p&gt;


	&lt;h3&gt;It has a fixed look&lt;/h3&gt;


	&lt;p&gt;As its name implies, &lt;em&gt;button_to&lt;/em&gt; creates buttons. Buttons don&amp;#8217;t look
like links and aren&amp;#8217;t styled the same way that links are. For some
design scenarios, this might be a problem.&lt;/p&gt;


	&lt;p&gt;(My view is that links should not be used to trigger unsafe
actions. In the same way that action-triggering &lt;span class="caps"&gt;GET&lt;/span&gt; requests violate
the spirit of the &lt;span class="caps"&gt;HTTP&lt;/span&gt; standards, action-triggering hypertext links
violate the spirit of the &lt;span class="caps"&gt;HTML&lt;/span&gt; standards. For this reason, I view this
limitation as a feature.)&lt;/p&gt;


	&lt;h3&gt;It is a no-no inside other forms&lt;/h3&gt;


	&lt;p&gt;Forms cannot be nested, and so &lt;em&gt;button_to&lt;/em&gt; cannot be used inside of
forms.&lt;/p&gt;


	&lt;p&gt;Fortunately, this limitation usually doesn&amp;#8217;t matter because when we
are inside of a form, we can use its buttons instead of
&lt;em&gt;button_to&lt;/em&gt;-created buttons to trigger actions. Still, there are some
circumstances where it does matter, such as the &amp;#8220;Amazon.com wish list&amp;#8221; 
scenario. In this scenario, we should consider &lt;a href="http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails#comment-110"&gt;other
options&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;The bottom line: Pick the low-hanging fruit&lt;/h3&gt;


	&lt;p&gt;While &lt;em&gt;button_to&lt;/em&gt; has its limitations, it does provide a simple solution
to the unsafe-GET problem for most real-world cases. I am glad that it
is now a part of Rails, and I offer a big thank-you to David for
accepting the patch.&lt;/p&gt;</description>
      <pubDate>Thu, 16 Jun 2005 12:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:29f013421357d69f430f725d21062807</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/06/16/the-button_to-helper-is-now-part-of-rails</link>
      <category>web development</category>
      <category>rails</category>
      <category>rails</category>
      <category>get</category>
      <category>gwa</category>
      <category>safe</category>
      <category>unsafe</category>
      <category>post</category>
      <category>link_to</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/46</trackback:ping>
    </item>
    <item>
      <title>Taking the unsafe GETs out of Rails</title>
      <description>&lt;div class="update"&gt;

	&lt;p&gt;&lt;em&gt;Update 2005-06-17:&lt;/em&gt; The &lt;em&gt;button_to&lt;/em&gt; helper, introduced below, has been incorporated into the Rails framework and will be a part of the Rails 1.0 release. See &lt;a href="http://community.moertel.com/ss/space/start/2005-06-16/1"&gt;Good news: The button_to helper is now part of Rails!&lt;/a&gt; for more.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Update 2005-05-28:&lt;/em&gt; I now have &lt;a href="http://community.moertel.com/ss/space/start/2005-05-08/1/button_to.rb"&gt;a more-recent version of the &lt;em&gt;button_to&lt;/em&gt; code&lt;/a&gt;, which adds support for the disabled &lt;span class="caps"&gt;HTML&lt;/span&gt; attribute. Thanks to Sean T Allen for the great idea and initial implementation.&lt;/p&gt;


&lt;/div&gt;

	&lt;p&gt;As I &lt;a href="http://community.moertel.com/ss/space/start/2005-05-06/1#Google_Web_Accelerator_offers_web_developers_an_important_opportunity"&gt;wrote earlier&lt;/a&gt;, it&amp;#8217;s time for web developers to do away with the fundamentally broken practice of using hypertext links to trigger dangerous events such as deleting things. One of the first places we ought to clean house is in the burgeoning &lt;a href="http://www.rubyonrails.org/"&gt;Rails web-application framework&lt;/a&gt;, where this practice is pervasive.&lt;/p&gt;


	&lt;p&gt;The primary culprit in Rails is the all-too-easy &lt;em&gt;link_to&lt;/em&gt; method, which is (presently) the orthodox means of creating links to any action, even unsafe ones. For example:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;link_to "Destroy", :controller =&amp;gt; 'accounts',
        :action =&amp;gt; 'destroy', :id =&amp;gt; 6
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The above code generates the following &lt;span class="caps"&gt;HTML&lt;/span&gt; hypertext link, which when followed will merrily delete account number 6:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;a href="/accounts/destroy/6"&amp;gt;Destroy&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Because this practice is dangerous and contrary to the decade-old convention that links be safe, the &lt;em&gt;link_to&lt;/em&gt; method thoughtfully lets us request that a Javascript confirmation dialog be tacked onto the link for added protection:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;link_to "Destroy", ...,  :confirm =&amp;gt; "Are you sure?" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The resulting &amp;#8220;safe&amp;#8221; &lt;span class="caps"&gt;HTML&lt;/span&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;a href="/accounts/destroy/6" 
   onclick="return confirm('Are you sure?');"&amp;gt;Destroy&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Unfortunately, the Javascript protection doesn&amp;#8217;t work. First, not all web browsers care about it. Lots of people surf with Javascript turned off. Second, a whole slew of things besides web browsers live on the Internet, and almost all of them are oblivious to Javascript. Web crawlers fall into this category. They will be more than happy to follow any link you feed to them. &amp;#8220;Hey, Googlebot just deleted every account in our database!&amp;#8221; Oops.&lt;/p&gt;


	&lt;p&gt;Thus another layer of protection is commonly used: authorization. The theory is that dangerous links can be safely corralled in the private parts of a web application, where the public and web crawlers cannot go. Only authorized users can get into those parts, and those users will be smart enough not to click on the truly dangerous links unless they really mean it.&lt;/p&gt;


	&lt;p&gt;The problem is, any number of intermediary agents can be operating &lt;em&gt;on behalf of an authorized user&lt;/em&gt;, and these agents are free to do anything the user is allowed to do, such as follow dangerous links. Google&amp;#8217;s Web Accelerator is one such agent. It tries to make your surfing faster by (among other things) pre-fetching the resources that are linked to on the pages you visit. And what happens if you, an authorized user, visit a page containing dangerous links? That&amp;#8217;s right, Web Accelerator will fetch the &amp;#8220;resources&amp;#8221; those links point to &amp;#8211; and delete a bunch of your stuff.&lt;/p&gt;


	&lt;p&gt;I hope by this point that I have argued convincingly that using links for unsafe actions is a bad idea. Even if you feel justified in ignoring the applicable parts of the &lt;span class="caps"&gt;HTTP&lt;/span&gt; RFCs, it&amp;#8217;s a bad idea. Even if you tack on Javascript confirmations and hide your links in authorization-protected zones of your site, it&amp;#8217;s a bad idea. It is, all around, a bad idea. Don&amp;#8217;t do it.&lt;/p&gt;


	&lt;p&gt;So what alternatives are there?  Read on for one possibility, &lt;em&gt;button_to&lt;/em&gt;.&lt;/p&gt;&lt;h3&gt;A &lt;em&gt;link_to&lt;/em&gt; alternative: &lt;em&gt;button_to&lt;/em&gt;&lt;/h3&gt;


	&lt;p&gt;If you shouldn&amp;#8217;t use links for unsafe actions, what should you use instead? Form buttons. Forms can be submitted via &lt;span class="caps"&gt;HTTP POST&lt;/span&gt; requests, and &lt;span class="caps"&gt;POST&lt;/span&gt; requests are understood to do potentially unsafe things. Web crawlers will not try to click your buttons. Intermediary user agents will not try to pre-submit your forms.&lt;/p&gt;


	&lt;p&gt;So, how do we make doing the right thing as easy as creating a link? My answer is 
&lt;em&gt;button_to&lt;/em&gt;, a method that takes the same parameters as the ever-popular &lt;em&gt;link_to&lt;/em&gt; but creates a tiny form that contains a single button instead of a link:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;button_to "Destroy", { :action =&amp;gt; 'destroy', :id =&amp;gt; 6 },
          :confirm =&amp;gt; "Are you sure?" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The resulting &lt;span class="caps"&gt;HTML &lt;/span&gt;(reformatted for your viewing pleasure):&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;form method="post" action="/accounts/destroy/6" class="button-to"&amp;gt;
  &amp;lt;div&amp;gt;&amp;lt;input onclick="return confirm('Are you sure?');" 
              value="Destroy" type="submit"&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The forms I create are given the class &lt;em&gt;button-to&lt;/em&gt;, which makes it easy to apply styles to them. With a little work, the buttons can look pretty darn good:&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://community.moertel.com/ss/space/start/2005-05-08/1/button_to.png" title="screen capture showing Edit and Destroy buttons created with the button_to method" alt="screen capture showing Edit and Destroy buttons created with the button_to method" /&gt;&lt;/p&gt;


	&lt;p&gt;So that&amp;#8217;s my plea: Use a button. It&amp;#8217;s a simple solution to a potentially ugly problem. There&amp;#8217;s no need for Ajax or other non-portable Javascript trickery. Just use a button.&lt;/p&gt;


	&lt;p&gt;And it&amp;#8217;s easy, too. In a few minutes, I was able to &amp;#8220;clean house&amp;#8221; on the Rails application I&amp;#8217;m developing.&lt;/p&gt;


	&lt;h3&gt;The code&lt;/h3&gt;


	&lt;p&gt;If you&amp;#8217;re interested, here&amp;#8217;s the code for &lt;em&gt;button_to&lt;/em&gt;. It&amp;#8217;s only ten lines, but the docs make it look much longer.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# Generates a form containing a sole button that submits to the URL
# given by _options_.  Use this method instead of +link_to+ for
# dangerous actions that do not have the safe HTTP GET semantics
# implied by using a hypertext link.
#
# The parameters are the same as for +url_to+.  Any _html_options_
# that you pass will be applied to the inner +input+ element.  The
# generated form element is given the class 'button-to', to which
# you can attach CSS styles for display purposes.
#
# Example 1:
#
#   # inside of controller 'feeds'
#   button_to "Edit", :action =&amp;gt; 'edit', :id =&amp;gt; 3
#
# Generates the following HTML (sans formatting):
#
#   &amp;lt;form method="post" action="/feeds/edit/3" class="button-to"&amp;gt;
#     &amp;lt;div&amp;gt;&amp;lt;input value="Edit" type="submit"&amp;gt;&amp;lt;/div&amp;gt;
#   &amp;lt;/form&amp;gt;
#
# Example 2:
#
#   button_to "Destroy", { :action =&amp;gt; 'destroy', :id =&amp;gt; 3 },
#             :confirm =&amp;gt; "Are you sure?" 
#
# Generates the following HTML (sans formatting):
#
#   &amp;lt;form method="post" action="/feeds/destroy/3" class="button-to"&amp;gt;
#     &amp;lt;div&amp;gt;&amp;lt;input onclick="return confirm('Are you sure?');" 
#                 value="Destroy" type="submit"&amp;gt;
#     &amp;lt;/div&amp;gt;
#   &amp;lt;/form&amp;gt;
# 
# *NOTE*: This method generates HTML code that represents a form.
# Forms are "block" content, which means that you should not try to
# insert them into your HTML where only inline content is expected.
# For example, you can legally insert a form inside of a +div+ or +td+
# element or in between +p+ elements, but not in the middle of a run
# of text.  (Bottom line:  Always validate your HTML before going
# public, especially if this paragraph seems confusing.)

def button_to(name, options = {}, html_options = nil)
  html_options = (html_options || {}).stringify_keys
  convert_confirm_option_to_javascript!(html_options)
  url, name = options.is_a?(String) ? 
    [ options,  name || options ] :
    [ url_for(options), name || url_for(options) ]
  html_options.merge!("type" =&amp;gt; "submit", "value" =&amp;gt; name)
  "&amp;lt;form method='post' action='#{h url}' class='button-to'&amp;gt;&amp;lt;div&amp;gt;" +
    tag("input", html_options) + "&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;" 
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Thanks for reading and happy unsafe-link hunting!&lt;/p&gt;</description>
      <pubDate>Sun, 08 May 2005 12:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:2e55c892774276d8ec6a19d9921e39d7</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails</link>
      <category>ruby</category>
      <category>web development</category>
      <category>rails</category>
      <category>rails</category>
      <category>get</category>
      <category>gwa</category>
      <category>safe</category>
      <category>unsafe</category>
      <category>post</category>
      <category>link_to</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/41</trackback:ping>
    </item>
    <item>
      <title>Google Web Accelerator offers web developers an important opportunity</title>
      <description>&lt;p&gt;Google Web Accelerator offers web developers an important opportunity
There has been a lot of heat lately about &lt;a href="http://webaccelerator.google.com/"&gt;Google&amp;#8217;s Web Accelerator&lt;/a&gt; (GWA)
&lt;a href="http://www.37signals.com/svn/archives2/google_web_accelerator_hey_not_so_fast_an_alert_for_web_app_designers.php"&gt;exposing serious problems&lt;/a&gt; in some popular web
applications. The problem, in short, is that these applications use
&lt;span class="caps"&gt;GET&lt;/span&gt;-based links that when followed perform dangerous actions such as
deleting records in a database. According to web standards going back
a decade, that is a no-no: Links should be safe to follow. Thus &lt;span class="caps"&gt;GWA&lt;/span&gt;,
expecting links to be safe, tries to help you out by pre-fetching
various resources that are linked to by the pages you
visit. Unfortunately, if the page you happen to be visiting contains
lots of dangerous links, &lt;span class="caps"&gt;GWA&lt;/span&gt; will innocently try to pre-fetch the
&amp;#8220;resources&amp;#8221; that the links point to, and in doing so will accidentally
delete a bunch of stuff. Oops.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s the backdrop for our real story, which is the response from the
community of web developers. What I find fascinating, and somewhat
disheartening, is the number of people who say the problem is Google&amp;#8217;s
to fix. Yes, there are a lot of broken web apps out there, and Google
could have been smarter about working around the minefields those apps
represent. But that&amp;#8217;s a side problem. The real problem is that there
are a lot of broken web apps out there, and they &lt;em&gt;do&lt;/em&gt; represent
minefields. Worse, a lot of web developers think it is acceptable to
brush aside fundamental conventions of the web going back a &lt;em&gt;decade&lt;/em&gt;
when they find it sexier to use &lt;span class="caps"&gt;GET&lt;/span&gt; instead of &lt;span class="caps"&gt;POST&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;What these developers overlook is that the web is not a bunch of
colorful pages with buttons, clickable links, and pretty
pictures. Rather the web is a distributed collection of hypertext
documents, each of which has a meaning that is given by standards that
most people have agreed to follow. While the collection may &lt;em&gt;look&lt;/em&gt; like
a bunch of colorful pages &lt;em&gt;in one particular visual presentation&lt;/em&gt;, it
really, truly is not.&lt;/p&gt;


	&lt;p&gt;Nevertheless, many web applications are designed with the prevailing
mindset that the meaning of the web is nothing more than how it looks
and behaves in a web browser. Even if those web applications are not
intended for use outside of a few approved browsers &amp;#8211; the escape
hatch that is often used to justify departures from the
standards &amp;#8211; this mindset is wrong.&lt;/p&gt;


	&lt;p&gt;The reason it is wrong is because, like it or not, web applications
are implemented in terms of protocols and languages that &lt;em&gt;mean
something&lt;/em&gt;. The bits and pieces of a web application each &lt;em&gt;mean
something&lt;/em&gt;, even if what they mean is not in harmony with the
designer&amp;#8217;s overall vision. What a web designer may see as a bold, red
link that says &amp;#8220;delete&amp;#8221; and is protected by a Javascript confirmation
dialog, is actually a hypertext reference &amp;#8211; a pointer
to another resource that the standards say should not be dangerous to
follow. Thus there is a fundamental mismatch between what the designer
is trying to say &amp;#8211; &amp;#8220;follow this link only if you
really, no-kidding want to delete something&amp;#8221; &amp;#8211; and
what his markup actually &lt;em&gt;means&lt;/em&gt;: &amp;#8220;this link is safe to follow.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The bottom line is that hypertext links are supposed to be
safe. Dangerous links can&amp;#8217;t be made &amp;#8220;safe&amp;#8221; by layering tricks on
them. Wrapping them with Javascript confirmation dialogs doesn&amp;#8217;t make
them safe. This trick fails fundamentally because the meaning of a
link doesn&amp;#8217;t change when there is Javascript associated with it. It
fails practically because not all consumers of hypertext evaluate
Javascript, nor do any standards suggest that they should. (This is
also why client-side validation cannot be trusted on the server side.)&lt;/p&gt;


	&lt;p&gt;Hiding dangerous links in authorization-controlled portions of a web
application does not make them safe, either. This trick might shield
the links from external spiders, but the standards allow for any
number of intermediary agents (such as Google&amp;#8217;s Web Accelerator) to
work &lt;em&gt;on behalf of an authorized user.&lt;/em&gt; Anything the user is authorized
to do, so are the user&amp;#8217;s agents. If the user can click the &amp;#8220;delete&amp;#8221; 
link, so can the agents.&lt;/p&gt;


	&lt;h4&gt;Let&amp;#8217;s answer the wake-up call.&lt;/h4&gt;


	&lt;p&gt;&lt;span class="caps"&gt;GWA&lt;/span&gt; is only the first of a new breed of
smarter user agents that promise to make the web a better place for
all of us. If you&amp;#8217;re a web developer, take the slew of problems that
&lt;span class="caps"&gt;GWA&lt;/span&gt; uncovered as a wake-up call. Even if Google works around your
problems, other user agents may not. As developers, it&amp;#8217;s time to admit
our mistakes and fix the stupid things that our web applications do.&lt;/p&gt;


	&lt;p&gt;First, let&amp;#8217;s drive a stake in the notion that dangerous links are OK
if we&amp;#8217;re &amp;#8220;careful.&amp;#8221; They&amp;#8217;re not. Dangerous links are
lazy. &amp;#8220;Confirming&amp;#8221; them with Javascript or &amp;#8220;hiding&amp;#8221; them behind
authorization doesn&amp;#8217;t work.&lt;/p&gt;


	&lt;p&gt;Second, let&amp;#8217;s clean house. Let&amp;#8217;s find those places where we have laced
our web applications with dangerous links and remove them. Break out
the forms! Long live the &lt;span class="caps"&gt;POST&lt;/span&gt;!&lt;/p&gt;


	&lt;p&gt;Third, let&amp;#8217;s take a look at how we got into this mess and try to learn
from our mistakes. Do we value sexiness more than substance? We like
to think that form follows function and that good design and good
implementation go hand in hand, but the reality of this debacle
suggests otherwise. I think the truth is that on the web, sexiness and
hype are what gets attention, and we seek attention more than we like
to admit.&lt;/p&gt;


	&lt;p&gt;Maybe the best thing for us is a good dose of humility. And, come to
think of it, that&amp;#8217;s just what Google&amp;#8217;s Web Accelerator offered us.&lt;/p&gt;</description>
      <pubDate>Fri, 06 May 2005 21:55:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:e542d7e0-94c6-4a4e-a41e-2b7ea7de7494</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/05/06/google-web-accelerator-offers-web-developers-an-important-opportunity</link>
      <category>web development</category>
      <category>rails</category>
      <category>get</category>
      <category>gwa</category>
      <category>safe</category>
      <category>unsafe</category>
      <category>post</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/210</trackback:ping>
    </item>
  </channel>
</rss>
