<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Mentalized</title>
		<link>http://mentalized.net/journal/</link>
		<description>The online journal of Jakob Skjerning, a freelance web application developer</description>
		<language>en-us</language>		
		<copyright>Copyright 2012, Jakob Skjerning</copyright>
		<lastBuildDate>Tue, 08 May 2012 18:08:43 +0100</lastBuildDate>
		<generator>Movable Type (http://www.movabletype.org/?v=5.04)</generator>
		<ttl>600</ttl>		
		
		
		<item>
			<title>Rails 3, ActionMailer, and Google Apps for Domains</title>
			<description><![CDATA[<p>After upgrading my <a href="http://redmine.org">Redmine</a> installation to Redmine 2 (the development branch) emails stopped being delivered.</p>

<p>I send emails through <a href="http://google.com/a">Google Apps for Domains</a>, so I had the following in my configuration.yml (previously email.yml):</p>

<pre><code>delivery_method: :smtp
smtp_settings:
  address: smtp.gmail.com
  port: 587
  domain: substancelab.com
  authentication: login
  user_name: "foobar@example.net"
  password: passw0rd
  tls: true
</code></pre>

<p>I am pretty sure it used to work before the upgrade, now; not so much.</p>
]]><![CDATA[<h2>Damn you, SSL</h2>

<p>Alas, when I ran <code>rake redmine:email:test</code> I kept getting a</p>

<pre><code>An error occurred while sending mail (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol)
</code></pre>

<h2>What is TLS even?</h2>

<p>I knew this has something to do with the TLS settings, but Google didn&#8217;t reveal any concrete, working advice. Adding <code>enable_starttls_auto: true</code>, which seems to be most prevalent solution didn&#8217;t change anything for me.</p>

<h2>One or the other, but not both</h2>

<p>Only after digging deep into <a href="http://apidock.com/rails/ActionMailer/Base">ActionMailer</a> and the <a href="https://github.com/mikel/mail">Mail gem</a> did I discover my problem.</p>

<p>Having <code>tls: true</code> in the settings was messing things up even if <code>starttls_auto</code> is enabled. Changing my settings to</p>

<pre><code>delivery_method: :smtp
smtp_settings:
  address: smtp.gmail.com
  port: 587
  domain: substancelab.com
  authentication: login
  user_name: "foobar@example.net"
  password: passw0rd
  enable_starttls_auto: true
</code></pre>

<p>made my email delivery work again.</p>

<p>File this under &#8220;blogged so you don&#8217;t have to suffer as I did&#8221;.</p>
]]></description>
			<link>http://mentalized.net/journal/2012/05/08/rails_3_actionmailer_and_google_apps_for_domains/</link>
			<guid isPermaLink="false">2141@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/05/08/rails_3_actionmailer_and_google_apps_for_domains/#comments</comments>
			<pubDate>Tue, 08 May 2012 18:08:43 +0100</pubDate>
			<category>Software</category>
		</item>
		
		<item>
			<title>All lights are green</title>
			<description><![CDATA[<p>The following are quotes from an actual email conversation with a potential customer.</p>

<blockquote><p>I'm no fan of bullshit <span class="caps">NDA</span>s, so I'm just sending this and I trust you that this'll not end up on Twitter or anything</p></blockquote>

<blockquote><p>I know quality has its price. [...] I don't like the wheeling and dealing either. If you say it's your rate, it's your rate</p></blockquote>

<blockquote><p>We would certainly not be against contributing back to the [open source] community</p></blockquote>

<p>I <em>must</em> close this deal.</p>]]></description>
			<link>http://mentalized.net/journal/2012/04/24/all_lights_are_green/</link>
			<guid isPermaLink="false">2140@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/04/24/all_lights_are_green/#comments</comments>
			<pubDate>Tue, 24 Apr 2012 14:44:43 +0100</pubDate>
			<category>Substance Lab</category>
		</item>
		
		<item>
			<title>CSS, links, gradients, rounded corners, and IE</title>
			<description><![CDATA[<p>On a project we were recently given a nicely designed button that we should implement.</p>

<p><img src="/files/journal/arrow_button/webkit_css.png" alt="Button using CSS rendered in Webkit" title="" /></p>

<p>No problem, I thought, that&#8217;s doable using CSS3. Behold, it was (non-interesting styles like font color and size are removed for clarity):</p>

<h3>HTML</h3>

<pre><code>&lt;a class="button" href="#"&gt;
  Styled with CSS &lt;small&gt;(no extra markup)&lt;/small&gt;
&lt;/a&gt;
</code></pre>

<h3>CSS</h3>

<pre><code>.button {
  background-color: #f98221;
  background: linear-gradient(top, #fec848, #f87d1a); /* Add vendor prefixes as needed */
  border-radius: 4px;
  border: 1px solid #eca253;
  box-shadow: rgba(0,0,0,0.2) 1px 2px 3px, inset rgba(255,255,255,0.7) 0 0 4px;
  display: inline-block;
  padding-left: 1em 36px 1em 18px;
  position: relative; /* Allows for absolute positioning relative to this element */
  text-decoration: none;
  text-shadow: rgba(0,0,0,0.3) 0.1em 0.1em 0.1em;
}
.button:before {
  background: url('icon_arrow_green.png') 50% 50% no-repeat;
  display: block;
  content: '';
  height: 100%;
  left: -2px;
  position: absolute;
  top: 0;
  width: 31px;
}
</code></pre>

<p>There was much rejoicing until the big blue elephant in the room reared its ugly head and pooped all over my nice and clean markup. Thank you, IE.</p>

<p><img src="/files/journal/arrow_button/ie9_css.png" alt="Button using CSS rendered in IE9" title="" /></p>
]]><![CDATA[<h2>Internet Explorer; still struggling to keep up</h2>

<p>While IE9 does support most the CSS that&#8217;s needed for this button style, it notably doesn&#8217;t support CSS gradients. However, you can apply a proprietary <code>Microsoft.gradient</code> filter, which does basically the same thing. Perfect!</p>

<h3>CSS</h3>

<pre><code>.button {
  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#fec848', endColorstr='#f87d1a');
}
</code></pre>

<p><img src="/files/journal/arrow_button/IE9_css_and_filter.png" alt="Button with IE filter rendered in IE9" title="" /></p>

<p>Unfortunately, the IE filter doesn&#8217;t work with border radius, thus the gradient isn&#8217;t rounded as it should be (note the square corners above). IE will not even clip the background gradient if we add <code>overflow: hidden</code>.</p>

<h2>Introducing a clipping element</h2>

<p>The solution is to create a wrapping element with <code>overflow: hidden</code> and <code>border-radius</code> that masks out the parts where the gradient shows through. Our markup now looks somewhat like</p>

<h3>HTML</h3>

<pre><code>&lt;a class="clipper" href="#"&gt;
  &lt;span class="button"&gt;
    CSS, filter, and extra markup
  &lt;/span&gt;
&lt;/a&gt;
</code></pre>

<h3>CSS</h3>

<pre><code>.clipper {
  overflow: hidden
}
</code></pre>

<p>This brings us really close to where we want to be. Unfortunately - although not unexpected - the arrow icon also gets clipped by the wrapping element.</p>

<p><img src="/files/journal/arrow_button/ie9_css_filter_and_extra_markup.png" alt="Button with IE filter and clipping element rendered in IE9" title="" /></p>

<h2>Moar markup!</h2>

<p>To work around that, we add more markup. First, we have our <code>a</code> element that simply works as a container for the visible elements inside it.</p>

<p>Inside the link, we generate an absolutely position element with the arrow icon (like in the first attempt).</p>

<p>In addition to that, we have our clipper element from before and inside that is a span with the text, to which we apply our actual button styles.</p>

<p>And boom, Internet Explorer now finally knows how to play nicely.</p>

<h2>Internet Explorer, it is always you&#8230;</h2>

<p>Unfortunately, Internet Explorer 8 doesn&#8217;t play nice with the above. While it doesn&#8217;t support border-radius at all, thus the corners aren&#8217;t rounded, it has <a href="http://stackoverflow.com/questions/5540177/ie8-z-index-on-before-and-after-css-selectors">a bug related to generated content and z-indexes</a>, making our icon render beneath the button:</p>

<p><img src="/files/journal/arrow_button/ie8_without_zindex_hack.png" alt="Button rendered in IE8" title="" /></p>

<p>To work around that, we can make our clipping element a relatively positioned element with a <em>negative</em> z-index:</p>

<pre><code>.button span {
    position: relative;
    z-index: -1;
}
</code></pre>

<p>This makes our button render well in Internet Explorer 8 and 9, Chrome, Safari, and Firefox with final markup and styles looking like this:</p>

<h3>HTML</h3>

<pre><code>&lt;a class="button" href="#"&gt;
  &lt;span&gt;
    &lt;span&gt;
      CSS, IE filter, and 2 spans&lt;br&gt;
      &lt;small&gt;It aint pretty, but it works&lt;/small&gt;
    &lt;/span&gt;
  &lt;/span&gt;
&lt;/a&gt;
</code></pre>

<h3>CSS</h3>

<pre><code>.button {
  display: inline-block;
  position: relative;
}
.button:before {
  background: url('icon_arrow_green.png') 50% 50% no-repeat;
  display: block;
  content: '';
  height: 100%;
  left: -2px;
  position: absolute;
  top: 0;
  width: 31px;
  z-index: 1; /* Make sure the ico overlays the button */
}
.button &gt; span {
  border-radius: 4px;
  box-shadow: rgba(0,0,0,0.2) 1px 2px 3px;
  display: inline-block;
  overflow: hidden;
  position: relative;
  z-index: -1;
}
.button &gt; span &gt; span {
  background-color: #f98221;
  background: linear-gradient(top, #fec848, #f87d1a);
  border-radius: 4px;
  border: 1px solid #eca253;
  box-shadow: inset rgba(255,255,255,0.7) 0 0 4px;
  color: #ffffff;
  display: inline-block;
  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#fec848', endColorstr='#f87d1a');
  padding: 1em 18px 1em 36px;
  text-decoration: none;
  text-shadow: rgba(0,0,0,0.3) 0.1em 0.1em 0.1em;
}
</code></pre>

<p>The above renders like this in Internet Explorer 9:</p>

<p><img src="/files/journal/arrow_button/ie9_css_filters_and_spans.png" alt="Button with IE filter, clipping element, all inside a link rendered in IE9" title="" /></p>

<h2>Voila</h2>

<p>There you go, a fully scalable link button styled primarily with CSS, using gradients and rounded corners and nearly pixel perfect rendered across browsers - even in Internet Explorer, at the cost of a little bit of markup pollution.</p>
]]></description>
			<link>http://mentalized.net/journal/2012/04/13/css_links_gradients_rounded_corners_and_ie/</link>
			<guid isPermaLink="false">2139@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/04/13/css_links_gradients_rounded_corners_and_ie/#comments</comments>
			<pubDate>Fri, 13 Apr 2012 12:39:18 +0100</pubDate>
			<category>Browsers</category>
		</item>
		
		<item>
			<title>Fact-checking the 40%</title>
			<description><![CDATA[<p>Last week I riffed on an <a href="http://www.onemorelevel.com/html-5-vs-flash-games/">infographic</a> which <a href="http://mentalized.net/journal/2012/02/05/flash_is_not_the_99/">erroneously claimed</a> that Flash is &#8220;supported on 99% of web browsers&#8221;.</p>

<p>They compared that number to 40%, which is supposedly the amount of web browsers that &#8220;HTML5 is supported by&#8221;.</p>

<p>Oh really, now?</p>
]]><![CDATA[<h2>What is &#8220;support&#8221;?</h2>

<p>First of all, the phrase &#8220;support HTML5&#8221; is terrible - what does that even mean? To the best of my knowledge there isn&#8217;t any browser (of the big ones) that doesn&#8217;t support at least some part of HTML5 in some way. Yes, even IE6.</p>

<p>The problem is, HTML5 is a complex thing composed of many different parts. Some browsers support some parts better than others - some, not so much.</p>

<h2>It&#8217;s all about games</h2>

<p>So let&#8217;s focus.</p>

<p>The infographic purports that Flash is better than HTML5 for games. The <a href="http://en.wikipedia.org/wiki/Canvas_element">HTML5 canvas</a> is what you&#8217;d use for drawing 2D shapes and whatnot for games, so I am going out on limb here and guess that what they&#8217;re looking at is support for <code>canvas</code>. </p>

<p>Thankfully, it&#8217;s fairly easy to get statistics on the market penetration for browsers supporting the HTML5 canvas element. <a href="http://caniuse.com">caniuse.com</a> has a <a href="http://caniuse.com/#feat=canvas">nifty table showing exactly that</a>.</p>

<p>According to that table, 69% of browsers support the canvas element.</p>

<h2>40 != 69 &amp;&amp; 99 != 96 &amp;&amp; 69 &lt; 96</h2>

<p>The claimed 40% is a long shot from the actual 69%. Sure, it&#8217;s way less than the <a href="http://mentalized.net/journal/2012/02/05/flash_is_not_the_99/">96%</a> potential market penetration Flash can achieve.</p>

<p>As I wrote in my last post, I don&#8217;t really care whether Flash is better than HTML5 for whatever you want to use it for. All the more power to you - as long as you don&#8217;t claim to be making websites with Flash.</p>

<p>But I do care about people being mislead with <del>made up</del>poorly  researched numbers and claims. Unfortunately, the infographic from <a href="http://www.onemorelevel.com/html-5-vs-flash-games/">OneMoreLevel.com</a> seems to have plenty of those.</p>
]]></description>
			<link>http://mentalized.net/journal/2012/02/13/fact-checking_the_40/</link>
			<guid isPermaLink="false">2134@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/02/13/fact-checking_the_40/#comments</comments>
			<pubDate>Mon, 13 Feb 2012 20:49:43 +0100</pubDate>
			<category>Technology</category>
		</item>
		
		<item>
			<title>Flash is not the 99%</title>
			<description><![CDATA[<p>An &#8220;<a href="http://www.onemorelevel.com/html-5-vs-flash-games/" title="HTML5 vs Flash games infographic">infographic</a>&#8221; showing some data points in the epic HTML5 vs Flash battle has recently made its rounds on Twitter and other sites.</p>

<p>I don&#8217;t care much for whether Flash is the bees knees for games, but I do care about people misleading people with data. And some of the data points depicted in the graphic didn&#8217;t quite sit right with me, so here&#8217;s an attempt at figuring at least one of them out.</p>

<blockquote>
  <p>Flash is supported by 99% of web browsers</p>
</blockquote>
]]><![CDATA[<h2>They literally mean 0%</h2>

<p>Taken literally, the statement that 99% of web browsers support Flash is flat out wrong. Fact is no browser supports Flash - at least not natively.</p>

<p>So that 99% figure should really be a flat 0%&#8230;</p>

<h2>1 in 5 is 20%</h2>

<p>Okay, fine, most browsers do support a method of displaying Flash content, namely the Flash Player plugin which is available as an optional download. However, only one of the major browsers - Chrome - actually <a href="http://en.wikipedia.org/wiki/Adobe_Flash_Player" title="Wikipedia: Adobe Flash Player">ships with the plugin installed</a>. </p>

<p>If we accept third party extensions as part of what a browser supports, the correct number here then becomes 20% - ie 1 of the 5 major browsers (Internet Explorer, Firefox, Chrome, Safari, and Opera) support Flash out of the box.</p>

<h2>25% market share</h2>

<p>There&#8217;s still some way before we reach 99%, though. And honestly, using the number of browsers as a base is pointless (but it serves as a nice illustration that statistics should rarely be taken at face value). It is more interesting to look at browser market shares in this case.</p>

<p>According to the <a href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers" title="Wikipedia: Usage share of web browsers">numbers from W3Counter</a>, Chromes market share was 24.6% in January 2012. This in turn means the market share of browsers able to display Flash content out of the box is roughly 25%.</p>

<p>Still not quite 99%.</p>

<h2>They do statistics differently in Flashland</h2>

<p>Let&#8217;s assume their wording is not entirely accurate. What they probably really meant to say is that 99% of internet requests come from a web browser that has Flash Player installed. Really, that&#8217;s the interesting figure if you plan on putting out Flash content.</p>

<p>However, that statements doesn&#8217;t seem quite right either.</p>

<p>Primarily because <a href="http://www.apple.com/hotnews/thoughts-on-flash/" title="Steve Jobs' Thoughts on Flash">iOS famously doesn&#8217;t support Flash</a>. In other words, no iPad, iPhone, or iPod Touch is able to display Flash content - at least not as part of the browser experience.</p>

<p>According to the <a href="http://www.w3counter.com/globalstats.php?year=2012&amp;month=1" title="W3Counter: January 2012">numbers from W3Counter</a>, iOS devices accounted for 4.5% of internet traffic in January 2012. Thus, there is no chance that the market share of Flash-supporting browsers can be higher than 95.5%.</p>

<h2>96%, and that&#8217;s my final offer</h2>

<p>So there we have it, this must be the number they&#8217;re thinking of. If we assume that every internet user actually installs the optional Flash Player - and I suspect this is a stretch, but I am not sure where to get reliable numbers on this - 96% of all internet traffic could come from a browser that is able to display Flash content.</p>

<p>That&#8217;s a huge, potential user base. </p>

<p>However, seeing that the 99% figure of the infographic is incorrect, I wonder which of the other numbers are misleading as well.</p>

<p>For example, if we extend the above definition to the HTML5 column, I am fairly sure that the number of internet requests coming from a browser able to display HTML5 content is vastly higher than 40% - but that&#8217;s a topic for another post.</p>
]]></description>
			<link>http://mentalized.net/journal/2012/02/05/flash_is_not_the_99/</link>
			<guid isPermaLink="false">2133@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/02/05/flash_is_not_the_99/#comments</comments>
			<pubDate>Sun, 05 Feb 2012 14:17:23 +0100</pubDate>
			<category>Technology</category>
		</item>
		
		<item>
			<title>Ruby SSL certificate verification errors</title>
			<description><![CDATA[<p>On a client project, we had recently installed <a href="https://github.com/technicalpickles/capistrano-campfire">capistrano-campfire</a> to get notifications in our <a href="http://campfirenow.com/">Campfire</a> chatroom whenever a deployment takes place.</p>

<p>Unfortunately I kept getting</p>

<pre><code>SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
</code></pre>

<p>when I tried deploying. There&#8217;s nothing quite like starting the year with SSL issues&#8230;</p>

<p>According to <a href="http://martinottenwaelter.fr/2010/12/ruby19-and-the-ssl-error/">this article</a> the problem</p>

<blockquote>
  <p>&#8230; comes from the fact that the new Ruby 1.9 installation doesn&#8217;t find the certification authority certificates (CA Certs) used to verify the authenticity of secured web servers.</p>
</blockquote>

<p>I my case, I was using Ruby 1.8 (well, <a href="http://www.rubyenterpriseedition.com/">REE</a>) on OS X Snow Leopard, but the problem - and solution - was the same nevertheless.</p>
]]><![CDATA[<h2>The cURL way</h2>

<p>The super easy solution is found on <a href="http://stackoverflow.com/questions/5711190/how-to-get-rid-of-opensslsslsslerror">Stack Overflow</a> (as always):</p>

<pre><code>sudo curl http://curl.haxx.se/ca/cacert.pem -o /opt/local/etc/openssl/cert.pem
</code></pre>

<p>This installs <a href="http://curl.haxx.se/ca/">Mozillas CS Root Certificates Bundle</a> at /opt/local/etc/openssl/cert.pem, where the certificates can be found by Rubys HTTP library without any extra configuration.</p>

<h2>Using MacPorts</h2>

<p>As an alternative to the above, you can use MacPorts to get the bundles (as mentioned in <a href="http://martinottenwaelter.fr/2010/12/ruby19-and-the-ssl-error/">this article</a>):</p>

<pre><code>$ sudo port install curl-ca-bundle
</code></pre>

<p>This installs the certificates bundle in /opt/local/etc/openssl/cert.pem.</p>

<p>You can then configure Ruby to use them:</p>

<pre><code>https.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt'
</code></pre>

<p>or if that isn&#8217;t feasible, simply link them up from the default location:</p>

<pre><code>$ sudo ln -s /opt/local/share/curl/curl-ca-bundle.crt /opt/local/etc/openssl/cert.pem
</code></pre>
]]></description>
			<link>http://mentalized.net/journal/2012/01/02/ruby_ssl_certificate_verification_errors/</link>
			<guid isPermaLink="false">2131@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2012/01/02/ruby_ssl_certificate_verification_errors/#comments</comments>
			<pubDate>Mon, 02 Jan 2012 09:52:24 +0100</pubDate>
			<category>Programming</category>
		</item>
		
		<item>
			<title>Dear Open Source Software</title>
			<description><![CDATA[<p>Dear Open Source Software</p>

<p>I don&#8217;t think I have ever written you before, but there is something I wanted to get off my chest.</p>

<p>I just wanted to let you know, that you rock! Just the other day, you saved my customer a bunch of money - and made me look like a hero.</p>

<p>Okay, I realize you only did so because I had done part of the work already. And I am probably giving you credit for something you didn&#8217;t really do, but thanks to you a team of strangers had implemented features I needed and given them back to me.</p>

<p>Also, the way you enable people I have never heard about to take something I have created and transform into something they can use, is mind boggling.</p>

<p>Thanks.</p>

<p>Yours, Jakob</p>

<p>PS: I know, I know&#8230; I don&#8217;t contribute often enough, and I will some day, I promise. Soon.</p>
]]>
</description>
			<link>http://mentalized.net/journal/2011/12/18/dear_open_source_software/</link>
			<guid isPermaLink="false">2127@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2011/12/18/dear_open_source_software/#comments</comments>
			<pubDate>Sun, 18 Dec 2011 15:56:46 +0100</pubDate>
			<category>Software</category>
		</item>
		
		<item>
			<title>Challenge the deadline</title>
			<description><![CDATA[<p>There are basically two kinds of deadlines: Real, and Arbitrary.</p>

<p>Real deadlines are those necessitated by some external, unchangeable event. For example legislation, the company running out of money, the CEO having to get up in front of the world press and announce the product, or a marketing campaign kicking off.</p>
]]><![CDATA[<h2>Arbitrary deadlines</h2>

<p>And then there are the much more common deadlines; The Arbitrary Deadline. They are recognizable by their basis in nothing at all - other than a decision that it would be nice to have X done by this or that date.</p>

<p>They are often employed in a naive attempt to speed up production. The thinking seems to be &#8220;give the wizkids a tight deadline, and they&#8217;ll really dig in and program the heck out of this&#8221;.</p>

<h2>Deadlines don&#8217;t change anything</h2>

<p>But here&#8217;s the thing about deadlines; they don&#8217;t make things any easier or faster to implement. No matter the deadline, you still have the same amount of work to do.</p>

<p>If your deadline is fixed, something else has to give; either quality or number of features. The Project Triangle sayeth so. </p>

<p>Give up on features and the product might not be what you imagined. Give up quality and <a href="http://mentalized.net/journal/2010/10/04/avoiding_the_big_rewrite/">you&#8217;ll pay for it later</a> - with interests.</p>

<p>I have yet to meet an arbitrary deadline that couldn&#8217;t be budged in the face of realities. Challenge the deadline before you lose your sleep over it.</p>
]]></description>
			<link>http://mentalized.net/journal/2011/11/30/challenge_the_deadline/</link>
			<guid isPermaLink="false">2129@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2011/11/30/challenge_the_deadline/#comments</comments>
			<pubDate>Wed, 30 Nov 2011 09:06:49 +0100</pubDate>
			<category>Business</category>
		</item>
		
		<item>
			<title>How to export CSV data from PostgreSQL</title>
			<description><![CDATA[<p>Just because I can never remember how to do this:</p>

<pre><code class="shell">psql my_database -c &quot;COPY (SELECT stuff FROM my_table) TO STDOUT CSV&quot; &gt; my_file.csv</code></pre>

<p>Works in at least PostgreSQL 8.4.</p>]]></description>
			<link>http://mentalized.net/journal/2011/11/07/how_to_export_csv_data_from_postgresql/</link>
			<guid isPermaLink="false">2128@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2011/11/07/how_to_export_csv_data_from_postgresql/#comments</comments>
			<pubDate>Mon, 07 Nov 2011 10:53:52 +0100</pubDate>
			<category>Technology</category>
		</item>
		
		<item>
			<title>Routing requests to local development environment</title>
			<description><![CDATA[<p>Some third party systems needs to send requests to your web application in order to work.</p>

<p><a href="http://facebook.com">Facebook</a> fetches the actual application, <a href="http://chargify.com/">Chargify</a> notifies you of subscription changes, payment gateways tell you the transaction has been accepted.</p>

<p>That&#8217;s fine in production where you have a public facing webserver running, but when you&#8217;re developing locally you have to jump through a few hoops.</p>
]]><![CDATA[<h2>Reverse SSH tunnel</h2>

<p>The common approach is to setup a <a href="http://www.howtoforge.com/reverse-ssh-tunneling">SSH tunnel</a> on a remote server and use that as endpoint for the third party service. This is pretty standard business and can be handled by a service like <a href="https://showoff.io/">Showoff</a>. Personally I just use basic SSH:</p>

<pre><code>ssh -vN koppen@example.com -R 3000:localhost:3000
</code></pre>

<p>As long as the above is running, all requests to port 3000 on example.com is received on localhost:3000.</p>

<p>If you&#8217;re developing Facebook apps, you can stop here. However, some third party services like <a href="http://chargify.com/">Chargify</a> and <a href="http://quickpay.net" title="Danish payment gateway">Quickpay</a> refuse to use anything but port 80 (and 443) for their communication. </p>

<p>While it is possible to setup the tunnel on port 80 remotely, my servers tend to already occupy port 80, so that&#8217;s a no go.</p>

<h2>Proxy passing</h2>

<p>The next piece of the puzzle then becomes routing to the SSH tunnel at port 3000 from port 80.</p>

<p>Since my development server is already running <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">Apache</a>, this is painfully easy. I just created a new site, using <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">mod_proxy</a> to forward requests to the given port:</p>

<pre><code>&lt;VirtualHost *:80&gt;
  ServerName tunnel.example.com
  ProxyPass / http://0.0.0.0:3000/ retry=0
&lt;/VirtualHost&gt;
</code></pre>

<p>(The retry=0 option to ProxyPass prevents the endpoint from being marked as bad for a period of time if it receives a request without my tunnel being active)</p>

<p>With this in place, any request to tunnel.example.com is passed to 0.0.0.0:3000 on the same server, where the SSH tunnel receives it and passes it to my local development server.</p>

<p>Success! And the best part is, this totally makes me feel like I am <a href="http://www.introversion.co.uk/uplink/screenshots/uplink4.gif">bouncing connections around in Uplink</a>.</p>
]]></description>
			<link>http://mentalized.net/journal/2011/10/19/routing_requests_to_local_development_environment/</link>
			<guid isPermaLink="false">2125@http://mentalized.net/journal/</guid>
			<comments>http://mentalized.net/journal/2011/10/19/routing_requests_to_local_development_environment/#comments</comments>
			<pubDate>Wed, 19 Oct 2011 09:58:33 +0100</pubDate>
			<category>Software</category>
		</item>
			
	</channel>
</rss>
