<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ruby Underground</title>
	<atom:link href="http://rubyunderground.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://rubyunderground.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 07 Dec 2009 19:19:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>RubySpec: Monkeypatch with Confidence</title>
		<link>http://rubyunderground.org/2009/12/rubyspec-monkeypatch-with-confidence/</link>
		<comments>http://rubyunderground.org/2009/12/rubyspec-monkeypatch-with-confidence/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 19:16:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[monkeypatch]]></category>
		<category><![CDATA[rubyspec]]></category>
		<category><![CDATA[vfs]]></category>

		<guid isPermaLink="false">http://rubyunderground.org/?p=12</guid>
		<description><![CDATA[<p>While the tagline of RubySpec is actually &#8220;The Standard You Trust&#8221; it might as well be &#8220;Monkeypatch with Confidence&#8221;.</p>
<p>Here&#8217;s the backstory:</p>
<p>Building TorqueBox, I ultimately wanted to be able to run a Ruby application from within a simple zip bundle of the app.  And handling everything that expects to be living in a relatively-addressable filesystem.  Not [...]]]></description>
			<content:encoded><![CDATA[<p>While the tagline of <a title="RubySpec" href="http://rubyspec.org/">RubySpec</a> is actually &#8220;The Standard You Trust&#8221; it might as well be &#8220;Monkeypatch with Confidence&#8221;.</p>
<p><em>Here&#8217;s the backstory:</em></p>
<p>Building <a title="TorqueBox" href="http://torquebox.org/">TorqueBox</a>, I ultimately wanted to be able to run a Ruby application from within a simple zip bundle of the app.  And handling everything that expects to be living in a relatively-addressable filesystem.  Not just <strong>require</strong> and <strong>load</strong>, but things like <strong>Dir['*.png']</strong> and <strong>File.stat(&#8230;)</strong>.</p>
<p>Plus, JBoss (upon which TorqueBox is built) has this cool ability to think of a jar-within-a-jar-within-a-jar (or a Russian doll nesting of zip files) as still a simple directory-based filesystem.</p>
<p>JRuby, though, isn&#8217;t quite as swift, in terms of paths for standard core library things such as <strong>File</strong>, or <strong>Dir</strong>, or <strong>IO</strong>.</p>
<p>To get this JBoss functionality (called <strong>VFS</strong> for <a title="JBoss VFS" href="http://java.dzone.com/news/jboss-virtual-file-system">Virtual File-System</a>) exposed to any arbitrary Ruby code, I&#8217;m having to monkeypatch <strong>File</strong>, <strong>Dir</strong>, <strong>IO</strong> and other classes.</p>
<p>For the most part, the rule for how these patches jack in is <em>&#8220;if this is a normal file/directory/io, let the normal core library handle it, otherwise, punt to VFS&#8221;</em>.</p>
<p>Given this rule, with VFS turned on, all existing code that doesn&#8217;t touch these zip/jar bundles should exhibit no regressions.  A great way to test that is using RubySpec.  I&#8217;m approaching this problem as treating JRuby-with-VFS as a new implementation of Ruby, to be tested alongside general JRuby support.  Enabling VFS should not cause JRuby to become any less compatible with the specs.</p>
<p>Contributors to the VFS gem can now <a title="TorqueBox RubySpec README" href="http://github.com/torquebox/torquebox/blob/master/vfs/README-RubySpec.txt">easily run the applicable RubySpecs against JRuby both with and without VFS enabled</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://rubyunderground.org/2009/12/rubyspec-monkeypatch-with-confidence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SWFUpload, Rails, REST, and Sessions</title>
		<link>http://rubyunderground.org/2009/11/swfupload-rails-rest-and-sessions/</link>
		<comments>http://rubyunderground.org/2009/11/swfupload-rails-rest-and-sessions/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 04:49:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[sessions]]></category>
		<category><![CDATA[swfupload]]></category>

		<guid isPermaLink="false">http://rubyunderground.org/?p=3</guid>
		<description><![CDATA[<p>To test TorqueBox, I&#8217;m always building little applications.</p>
<p>My latest little application involved uploading a user avatar image, which my app, using Paperclip, would shuffle to Amazon S3.</p>
<p>Form uploads are cool, but AJAXy Flash uploads are cooler.  So I grabbed SWFUpload from the conveniently-named sfwupload.org.</p>
<p>Integrating it into my application was a slight challenge, alas.</p>
<p>My User model [...]]]></description>
			<content:encoded><![CDATA[<p>To test TorqueBox, I&#8217;m always building little applications.</p>
<p>My latest little application involved uploading a user avatar image, which my app, using <a title="paperclip on github" href="http://github.com/thoughtbot/paperclip">Paperclip</a>, would shuffle to Amazon S3.</p>
<p>Form uploads are cool, but AJAXy Flash uploads are cooler.  So I grabbed SWFUpload from the conveniently-named <a title="SWFUpload.org" href="http://swfupload.org/">sfwupload.org</a>.</p>
<p>Integrating it into my application was a slight challenge, alas.</p>
<p>My <strong>User</strong> model directly holds the <strong>avatar_*</strong> columns Paperclip wants, in the form of</p>
<ul>
<li>avatar_file_name</li>
<li>avatar_content_type</li>
<li>avatar_file_size</li>
<li>avatar_updated_at</li>
</ul>
<p>To my feeble mind, this seems like a <strong>PUT</strong> on an existing User resource, if I want to be RESTful.</p>
<p>SWFUpload will gleefully do a <strong>POST</strong>, and I can add a <strong>_method=PUT</strong> to my parameters.  This is a concession Rails has made to the rest of the world, realizing that not everything supports every HTTP verb when you want it to.  So, Rails lets you do a <strong>POST</strong>, and tell it what verb you <em>really</em> meant through a parameter named <strong>_method</strong>.  Rails only respects <strong>_method</strong>, though, if it&#8217;s in the <strong>POST</strong> parameters.  So I can&#8217;t use the query-string to inject the psuedo <strong>PUT</strong> (or <strong>DELETE</strong> or &#8230;).</p>
<p>But SWFUpload (and most anything Flash) doesn&#8217;t participate in the containing browser session.  It doesn&#8217;t have my session cookie.  Or it doesn&#8217;t send it, if it does. Without session information, the server doesn&#8217;t really know who is sending this octet stream at the URL. So, how do I secure this update_user execution, if I can&#8217;t pass a session cookie?</p>
<p>SWFUpload has an extension to include every cookie as a parameter in the request.  It just adds name=value pairs for each cookie into the post parameters, alongside the <strong>_method</strong> and anything else you&#8217;ve specified.  So, if you had a cookie named <strong>session_id</strong>, it&#8217;d get added to the form paramters as <strong>session_id</strong>.</p>
<p>But with TorqueBox, the Rack session piggybacks upon the Java Servlet session, which, unfortunately, doesn&#8217;t know to inspect the POST parameters. By default, the servlet container is looking for a cookie.  I attempted to write a custom valve for the Tomcat request chain, but I only had reliable access to query parameters, not post parameters of the multipart form.</p>
<p>This makes sense, since the <strong>POST</strong> body is conceivably large, and is 100% the responsibility of the application. App servers don&#8217;t typically go mucking around in it on their own.  The application expects to be able to get an input stream for the POST body and ready starting from byte 0.  This means either massive buffering, or the simply that the app-server gives it to the app unmolested (and uninspected).</p>
<p>And since Rails expects <strong>_method</strong> to be in the POST parameters, but session cookie information could only be inspected if present in the URL, I came to an impasse, I thought.</p>
<p>To sum up:</p>
<ul>
<li>Updating a User&#8217;s avatar is a <strong>PUT</strong> request against the <strong>User</strong> resource</li>
<li>SWFUpload can only do a <strong>POST</strong></li>
<li>Rails lets us tunnel <strong>PUT</strong> through <strong>POST</strong> using <strong>_method=PUT</strong></li>
<li><strong>_method=PUT</strong> must be in the <strong>POST</strong> parameters, not URL bits.</li>
<li>SWFUpload can inject cookies request parameters.</li>
<li>SWFUpload can use either URL-based query parameters XOR <strong>POST</strong> parameters, but not both.</li>
<li>Session lookup can&#8217;t take advantage of <strong>POST</strong> parameters, only URL bits.</li>
</ul>
<p>Though, without any other magic involved, our Java Servlet-based session can be divined by looking for a suffix on the URL of <strong>;jsessionid=&lt;id&gt;</strong>.</p>
<p>For instance, you might have come across some Google-cached URLs such as</p>
<ul>
<li>http://foo.com/products.jsp;jsessionid=918jk2j9j09j213</li>
</ul>
<p>That&#8217;s the Java app-server&#8217;s method of passing session cookie information via URL.</p>
<p>It probably breaks 7 of the top 5 tenets of RESTful architectures, but it works.  If we can use this method for passing our session cookie during the upload, then we can successfully secure this interaction.</p>
<p>Ultimately, SWFUpload does a <strong>POST</strong> to the User resource URL, with <strong>;jsession=&lt;id&gt;</strong> appended, and adds the <strong>_method=PUT</strong> to the <strong>POST</strong> parameters.  TorqueBox adds a <strong>url_suffix()</strong> method to the <strong>session</strong> object, which produces this full suffix.</p>
<p>Similar to this:</p>
<pre><code>
$upload_control.swfupload({
  upload_url: '#{url_for(user)}#{session.url_suffix}',
  post_params: {
    _method: 'PUT',
    authenticity_token: '#{form_authenticity_token}',
  },
  use_query_string: false});
</code></pre>
<p>Now we successfully pass session information, use CSRF-protection, and still communicate with a nicely RESTful controller on the back-end.</p>
<p>RESTful, Flashy, AJAXy, CSRF-protected and secure.  I&#8217;d call that a good day.</p>
]]></content:encoded>
			<wfw:commentRss>http://rubyunderground.org/2009/11/swfupload-rails-rest-and-sessions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
