<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-5255499813611899239</atom:id><lastBuildDate>Sat, 17 Mar 2012 15:32:45 +0000</lastBuildDate><category>p2p</category><category>eventmachine ruby</category><category>cygwin</category><category>rails</category><title>Nils Franzén</title><description></description><link>http://www.franzens.org/</link><managingEditor>noreply@blogger.com (Nils Franzén)</managingEditor><generator>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5255499813611899239.post-5324856947322068870</guid><pubDate>Sun, 16 Oct 2011 19:32:00 +0000</pubDate><atom:updated>2011-10-17T06:57:51.691+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>eventmachine ruby</category><title>Writing a minimalistic web-server using event machine</title><description>I wanted a small and efficient web-server that can handle large amount of http request that is easy to play around with. The &lt;a href="https://github.com/eventmachine/eventmachine"&gt;EventMachine&lt;/a&gt; is a good candidate together with the http parser provided by &lt;a href="https://github.com/macournoyer/thin"&gt;Thin&lt;/a&gt;. I didn't know much about thin when I started this exercise, but it is also built on top of EventMachine and is gaining in popularity according to this &lt;a href="http://blog.newrelic.com/2011/09/28/state-of-the-stack-a-ruby-on-rails-benchmarking-report-sept-2011/"&gt;State of the stack&lt;/a&gt; article.

&lt;p&gt;
But anyway, if you want a simple bare-bones web server with no fluff, continue reading...
&lt;/p&gt;

&lt;p&gt;
Before we start with the actual implemtnation, we need to install some ruby gems. This is easily done by running the following commands in your shell
&lt;/p&gt;

&lt;pre&gt;
gem install eventmachine
gem install thin
&lt;/pre&gt;

&lt;p&gt;
The server is pretty standard setup using eventmachine and looks like this
&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;
# FILE: server.rb

require 'rubygems'
require 'eventmachine'
require_relative './thin_http_parser.rb'

# Freeze some HTTP header names &amp; values
KEEPALIVE = "Connection: Keep-Alive\r\n".freeze

class RequestHandler &lt; EM::Connection
  def post_init
    @parser = RequestParser.new
  end

  def receive_data(data)
    handle_http_request if @parser.parse(data)
  end

  def handle_http_request
    p [@parser.env, @parser.body.string]
    keep_alive = @parser.persistent?

    data = "OK"
    send_data("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: #{data.bytesize}\r\n#{ keep_alive  ? KEEPALIVE.clone : nil}\r\n#{data}")
    
    if keep_alive
      post_init
    else
      close_connection_after_writing
    end
  end
end

host,port = "0.0.0.0", 8083
puts "Starting server on #{host}:#{port}, #{EM::set_descriptor_table_size(32768)} sockets"
EM.run do
  EM.start_server host, port, RequestHandler
  if ARGV.size &gt; 0
    forks = ARGV[0].to_i
    puts "... forking #{forks} times =&gt; #{2**forks} instances"
    forks.times { fork }
  end
end
&lt;/pre&gt;

&lt;p&gt;
At last, we need an http parser. I tried both writing my own in pure ruby and the EM::P::HeaderAndContentProtocol parser. But in then end I used the thin parser since it was the fastet parser and it is easy to integrate. This is the code for the parser
&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
# FILE: thin_http_parser.rb

require 'rubygems'
# Uncomment this line if 'thin_parser' is not found
# require 'thin' 
require 'thin_parser'
require 'stringio'

# Freeze some HTTP header names &amp; values
HTTP_VERSION      = 'HTTP_VERSION'.freeze
HTTP_1_0          = 'HTTP/1.0'.freeze
CONTENT_LENGTH    = 'CONTENT_LENGTH'.freeze
CONNECTION        = 'HTTP_CONNECTION'.freeze
KEEP_ALIVE_REGEXP = /\bkeep-alive\b/i.freeze
CLOSE_REGEXP      = /\bclose\b/i.freeze

# Freeze some Rack header names
RACK_INPUT        = 'rack.input'.freeze

# A request sent by the client to the server.
class RequestParser
  INITIAL_BODY      = ''

  # Force external_encoding of request's body to ASCII_8BIT
  INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode!)

  # CGI-like request environment variables
  attr_reader :env

  # Unparsed data of the request
  attr_reader :data

  # Request body
  attr_reader :body

  def initialize
    @parser   = Thin::HttpParser.new
    @data     = ''
    @nparsed  = 0
    @body     = StringIO.new(INITIAL_BODY.dup)
    @env      = {
      RACK_INPUT        =&gt; @body,
    }
  end

  # Parse a chunk of data into the request environment
  # Returns +true+ if the parsing is complete.
  def parse(data)
    if @parser.finished?  # Header finished, can only be some more body
      body &lt;&lt; data
    else                  # Parse more header using the super parser
      @data &lt;&lt; data
      @nparsed = @parser.execute(@env, @data, @nparsed)
    end

    if finished?   # Check if header and body are complete
      @data = nil
      @body.rewind
      true         # Request is fully parsed
    else
      false        # Not finished, need more data
    end
  end

  # +true+ if headers and body are finished parsing
  def finished?
    @parser.finished? &amp;&amp; @body.size &gt;= content_length
  end

  # Expected size of the body
  def content_length
    @env[CONTENT_LENGTH].to_i
  end

  # Returns +true+ if the client expect the connection to be persistent.
  def persistent?
    # Clients and servers SHOULD NOT assume that a persistent connection
    # is maintained for HTTP versions less than 1.1 unless it is explicitly
    # signaled. (http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html)
    if @env[HTTP_VERSION] == HTTP_1_0
      @env[CONNECTION] =~ KEEP_ALIVE_REGEXP

    # HTTP/1.1 client intends to maintain a persistent connection unless
    # a Connection header including the connection-token "close" was sent
    # in the request
    else
      @env[CONNECTION].nil? || @env[CONNECTION] !~ CLOSE_REGEXP
    end
  end
end
&lt;/pre&gt;

The server is started by running

&lt;pre&gt;
ruby server.rb
&lt;/pre&gt;

&lt;p&gt;
It is also possible to &lt;b&gt;fork&lt;/b&gt; the process in order to increase the performance by adding an integer at the end of the start line. If I want to start 4 instances of server, I currently run
&lt;/p&gt;

&lt;pre&gt;
ruby server.rb 2
&lt;/pre&gt;

&lt;p&gt;There is not much of an idea to run a lot more instances than you have cores on the machine, since it will only slow things down. And be aware that "fork" doesn't work out of the box on windows OS.
&lt;/p&gt;

&lt;p&gt;With this setup, I easily get 100.000+ reqs/seconds using &lt;a href="http://httpd.apache.org/docs/2.0/programs/ab.html"&gt;ab&lt;/a&gt; with keep-alive switch (-k) on a medium core i5 processor.
&lt;/p&gt;


&lt;p&gt;To summarize my little hacking is that I really enjoy the simple and yet powerful API that EventMachine offers. You can really write compact code and yet good performing servers with Ruby and EventMachine&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5255499813611899239-5324856947322068870?l=www.franzens.org' alt='' /&gt;&lt;/div&gt;</description><link>http://www.franzens.org/2011/10/writing-minimalistic-web-server-using.html</link><author>noreply@blogger.com (Nils Franzén)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5255499813611899239.post-6277396636094165865</guid><pubDate>Tue, 30 Jun 2009 08:31:00 +0000</pubDate><atom:updated>2009-11-23T08:45:40.977+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>p2p</category><title>Global Gaming Factory is buying The Pirate Bay and Peerialism</title><description>&lt;p&gt;Now it is public, we (Peerialism) and The Pirate Bay is getting bought by Global Gaming Factory.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.aktietorget.se/NewsItem.aspx?ID=52051"&gt;http://www.aktietorget.se/NewsItem.aspx?ID=52051&lt;/a&gt; (in Swedish)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Our experience with Global Gaming Factory is so far not that good, &lt;a href="http://news.cnet.com/8301-1023_3-10314557-93.html"&gt;http://news.cnet.com/8301-1023_3-10314557-93.html &lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5255499813611899239-6277396636094165865?l=www.franzens.org' alt='' /&gt;&lt;/div&gt;</description><link>http://www.franzens.org/2009/01/global-gaming-factory-is-buying-pirate.html</link><author>noreply@blogger.com (Nils Franzén)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5255499813611899239.post-4057476838210646871</guid><pubDate>Sun, 04 Jan 2009 17:54:00 +0000</pubDate><atom:updated>2010-01-29T17:08:10.280+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>rails</category><title>Using Google Federated Login in your Rails Application</title><description>&lt;p&gt;
I'm in the progress of building an &lt;a href="http://code.google.com/android/index.html"&gt;Android application&lt;/a&gt; with a &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; backend. On Android, one of the first things you need to do is to tie the phone to a Google account. So to make it easier for the end users, I thought that I maybe could skip my own user account management and instead piggy back on the Google accounts.&lt;/p&gt;

&lt;p&gt;
After some initial research I found that Google recently released a &lt;a href="http://google-code-updates.blogspot.com/2008/10/google-moves-towards-single-sign-on.html"&gt;single sign-on&lt;/a&gt; using OpenID. There are some sites that use the Google Federated Login, e.g. &lt;a href="http://www.zoho.com/"&gt;www.zoho.com&lt;/a&gt;, &lt;a href="http://www.buxfer.com/" target="_blank" rel="nofollow"&gt;www.buxfer.com&lt;/a&gt; and &lt;a href="http://www.plaxo.com/openid" target="_blank" rel="nofollow"&gt;http://www.plaxo.com/openid&lt;/a&gt; (look for the Google login button). However, it turned out that it wasn't really OpenID, it was something that &lt;a href="http://neosmart.net/blog/2008/google-doesnt-use-openid/"&gt;resembles of OpenID&lt;/a&gt;. Even thought it isn't pure OpenID, it does everything I want anyway, so I started to code the login using the "official" &lt;a href="http://github.com/rails/open_id_authentication/tree/master"&gt;OpenID Authentication&lt;/a&gt; plugin.&lt;/p&gt;

&lt;p&gt;
From Google Federated Login you can currently only get the email of a user, but it was impossible to get the email using the OpenID Authentication plugin. After some detective work it was clear that Google Federated Login uses AX attributes, not the SReg attributes that is used by default in the plugin. So my solution is to patch the plugin with the code below. You can add the code to your session controller and it will work with the Google OpenID URI.&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
  #
  # If we want to get the GMail address for a user using Google Federated Login,
  # we need to work with AX attributes, not SReg attributes which is used by
  # default.
  #
  # To solve this Ax/SReg attribute problem we patch the OpenIdAuthentication
  # module to use AX attributes when talking to the Google OpenID server
  #
  # This patch is based on the source from github[1], January 4, 2009
  #
  # 1. http://github.com/rails/open_id_authentication/commits/master
  #
  module ::OpenIdAuthentication
    require 'openid/extensions/ax'

    private
    def add_simple_registration_fields(open_id_request, fields)
      if is_google_federated_login?(open_id_request)
        ax_request = OpenID::AX::FetchRequest.new
        # Only the email attribute is currently supported by google federated login
        email_attr = OpenID::AX::AttrInfo.new('http://schema.openid.net/contact/email', 'email', true)
        ax_request.add(email_attr)
        open_id_request.add_extension(ax_request)
      else
        sreg_request = OpenID::SReg::Request.new
        sreg_request.request_fields(Array(fields[:required]).map(&amp;:to_s), true) if fields[:required]
        sreg_request.request_fields(Array(fields[:optional]).map(&amp;:to_s), false) if fields[:optional]
        sreg_request.policy_url = fields[:policy_url] if fields[:policy_url]
        open_id_request.add_extension(sreg_request)
      end
    end

def complete_open_id_authentication
      params_with_path = params.reject { |key, value| request.path_parameters[key] }
      params_with_path.delete(:format)
      open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) }
      identity_url     = normalize_identifier(open_id_response.display_identifier) if open_id_response.display_identifier

case open_id_response.status
      when OpenID::Consumer::SUCCESS
        if is_google_federated_login?(open_id_response)
          yield Result[:successful], params['openid.identity'], OpenID::AX::FetchResponse.from_success_response(open_id_response)
        else
          yield Result[:successful], identity_url, OpenID::SReg::Response.from_success_response(open_id_response)
        end
      when OpenID::Consumer::CANCEL
        yield Result[:canceled], identity_url, nil
      when OpenID::Consumer::FAILURE
        yield Result[:failed], identity_url, nil
      when OpenID::Consumer::SETUP_NEEDED
        yield Result[:setup_needed], open_id_response.setup_url, nil
      end
    end

def is_google_federated_login?(request_response)
      return request_response.endpoint.server_url == "https://www.google.com/accounts/o8/ud"
    end
  end
&lt;/pre&gt;

&lt;p&gt;
And in the &lt;code&gt;create&lt;/code&gt; method (following the example given in the README for the plugin), I have currently hard-coded the OpenID URI to 'https://www.google.com/accounts/o8/id', but you could get it from a form as well. Note that we have two cases to get the email depending if a Google OpenID URI or a regular OpenID URI was used.&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
  def create
    openid_url = 'https://www.google.com/accounts/o8/id'
    authenticate_with_open_id(openid_url, {:required =&amp;gt; [ 'email' ] }) do |result, identity_url, registration|
      case result.status
      when :missing
        failed_login "Sorry, the OpenID server couldn't be found"
      when :invalid
        failed_login "Sorry, but this does not appear to be a valid OpenID"
      when :canceled
        failed_login "OpenID verification was canceled"
      when :failed
        failed_login "Sorry, the OpenID verification failed"
      when :successful
        if registration.class.to_s == "OpenID::AX::FetchResponse"
          email = registration['http://schema.openid.net/contact/email']
        else
          email = registration['email']
        end
        # Find (or create user) based on identity_url
# Note that email is not set when the user has selected 'always remember' in the Google login page for subsequent logins
      end
    end
  end
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Update January 9:&lt;/strong&gt; The code was updated to solve the  Google 'always remember' problem&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update January 15:&lt;/strong&gt; &lt;a href="http://groups.google.com/group/google-federated-login-api/web/the-most-important-technical-issue-in-using-the-google-accounts-api"&gt;The most important technical issue in using the Google Federated Login API&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5255499813611899239-4057476838210646871?l=www.franzens.org' alt='' /&gt;&lt;/div&gt;</description><link>http://www.franzens.org/2009/01/using-google-federated-login-in-your.html</link><author>noreply@blogger.com (Nils Franzén)</author><thr:total>10</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5255499813611899239.post-7653685423357640011</guid><pubDate>Thu, 06 Sep 2007 20:39:00 +0000</pubDate><atom:updated>2010-01-29T16:52:15.300+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>cygwin</category><title>An indispensable bash function for Cygwin</title><description>Put the following code in your &lt;code&gt;.bashrc&lt;/code&gt; file:

&lt;pre class="brush: bash"&gt;
function open() {
   if [ "$1" = "" ]
   then
      rundll32 url.dll,FileProtocolHandler .
   else
      rundll32 url.dll,FileProtocolHandler `cygpath -w "$1"`
   fi
}
&lt;/pre&gt;

Now you can use the &lt;em&gt;open&lt;/em&gt; command.

&lt;ul&gt;
  &lt;li&gt;Type &lt;code&gt;open http://www.franzens.org&lt;/code&gt; to fire up your web browser and point it to this site.&lt;/li&gt;
  &lt;li&gt;Type &lt;code&gt;open some_document.doc&lt;/code&gt; to start Microsoft Word (or Open Office) with specified document.&lt;/li&gt;
  &lt;li&gt;Type &lt;code&gt;open some_document.txt&lt;/code&gt; to start notepad with specified document.&lt;/li&gt;
  &lt;li&gt;Type &lt;code&gt;open&lt;/code&gt; to launch the explorer in current directory.&lt;/li&gt;&lt;br/&gt; &lt;li&gt;Type &lt;code&gt;open //some_network_path/foo/bar&lt;/code&gt; to launch the explorer in specified directory.&lt;/li&gt;
&lt;/ul&gt;

I think you see the pattern above. I use the &lt;em&gt;open&lt;/em&gt; command all the time and it is really useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5255499813611899239-7653685423357640011?l=www.franzens.org' alt='' /&gt;&lt;/div&gt;</description><link>http://www.franzens.org/2007/09/indispensable-bash-function-for-cygwin.html</link><author>noreply@blogger.com (Nils Franzén)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-5255499813611899239.post-7967783923140762476</guid><pubDate>Sat, 12 May 2007 21:15:00 +0000</pubDate><atom:updated>2011-10-21T10:59:28.368+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>rails</category><title>Visualize Models 1.1</title><description>&lt;a href="http://visualizemodels.rubyforge.org/"&gt;Visualize Models&lt;/a&gt; is a small rake script that will generate .png images for Ruby On Rails models (i.e. the database tables) that will display the table/column information. The associations between tables is based on the default Ruby On Rails naming convention (i.e. &amp;lt;table&amp;gt;_id columns). See image below for the &lt;a href="http://www.typosphere.org/"&gt;typo blog&lt;/a&gt; models:

&lt;p align="center"&gt;&lt;a href="http://test.franzens.org/wp-content/uploads/2007/05/typo.png" title="Typo Blog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-8P_A6_sZNpU/TqEz7DYs83I/AAAAAAAAACo/A8dUkxlzQlU/s1600/typo_blog.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="200" width="194" src="http://4.bp.blogspot.com/-8P_A6_sZNpU/TqEz7DYs83I/AAAAAAAAACo/A8dUkxlzQlU/s200/typo_blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;




Install as a plugin. From your rails application root, run

&lt;pre class="brush: shell"&gt;ruby script/plugin install svn://rubyforge.org//var/svn/visualizemodels/visualize_models&lt;/pre&gt;

Run the plugin with:

&lt;pre class="brush: shell"&gt;rake visualize_models&lt;/pre&gt;

This plugin depends on GraphViz, which you can find &lt;a href="http://www.graphviz.org/"&gt;here&lt;/a&gt;.&lt;br/&gt;

&lt;p&gt;If you're a Mac user, the &lt;a href="http://darwinports.opendarwin.org/"&gt;Darwin port&lt;/a&gt; of GraphViz seems to work better. Just do:
&lt;pre class="brush: shell"&gt; sudo port install graphviz&lt;/pre&gt;
&lt;/p&gt;

This program has its roots in the &lt;a href="http://pragdave.pragprog.com/pragdave/2006/02/annotate_models.html"&gt;Annotate Models&lt;/a&gt; by Dave Thomas. See also the RubyForge &lt;a href="http://rubyforge.org/projects/visualizemodels/"&gt;project page&lt;/a&gt; for additional info.

&lt;p&gt;In addition to &lt;a href="http://visualizemodels.rubyforge.org/"&gt;Visualize Models&lt;/a&gt; there are two (that I'm aware of) other projects that you can use to visualize the database in Ruby On Rails:
&lt;ul&gt;
 &lt;li&gt;&lt;a href="http://rav.rubyforge.org/"&gt;Rails Application Visualizer&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://railroad.rubyforge.org/"&gt;RailRoad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know about any additional resources to visualize rails models, please drop me a mail at nils@&amp;lt;this domain&amp;gt;.
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Fixed the ActiveSupport::Inflector in SVN now as noted in the comments. Visualize_models works out of the box for rails 2.2.2 and later now&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5255499813611899239-7967783923140762476?l=www.franzens.org' alt='' /&gt;&lt;/div&gt;</description><link>http://www.franzens.org/2007/05/visualize-models-11.html</link><author>noreply@blogger.com (Nils Franzén)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-8P_A6_sZNpU/TqEz7DYs83I/AAAAAAAAACo/A8dUkxlzQlU/s72-c/typo_blog.png' height='72' width='72'/><thr:total>9</thr:total></item></channel></rss>
