helion-prime
home about us blogs contacts

Archive for the ‘general programming’ Category

Multi-domain applications in Ruby on Rails

Thursday, September 3rd, 2009

preamble

Ruby on Rails is a great framework that still luck some common features, among them: multi-domain support.
Here I will describe fast solution that doesn’t work for every browser and another one that do the work.

Ok, you did your homework and google something like ‘ruby on rails multi-domain’.
Very often provided solution:

edit environment.rb

1
config.action_controller.session = {:domain => '.mydomain.com'}

With that parameter Rails always read cookies from same domain. In real some browsers forbid for applications to read cookies from other domain due to insecurity of that operation. And as Mozilla Firefox in set of browsers that forbid that we just need another solution.

Now it’s clear that we should implement necessary functionality other way.

Here we go:

1. will store session ID in the database(by default Rails2 store it in cookies)

environment.rb:

1
config.action_controller.session_store = :active_record_store

and then execute rake task that create necessary DB migration:

1
rake db:sessions:create

Apply it with: rake db:migrate.

2. setup session parameters

environment.rb:

1
2
3
4
5
6
7
8
9
require "rubygems"
require "active_support"

config.action_controller.session = {
   :session_key => '_myapp_session_id',    # session identification key
   :secret      => '89sHslddfsd98klasdKd', # hash code of session generator(make it random and longer)
   :cookie_only => false,
   :expire_after => 1.week,                # TTL (time to live)
}

3. let’s create session creation handler

application_controller.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
before_filter { |controller|
   opts = controller.request.session_options
   key = opts[:key]

   # use session ID if it's passed
   if controller.params[key]       
      # session initialization with old ID
      controller.session[:nothing]

      opts[:id] = controller.params[key]
      controller.request.session_options = opts
     
      # session initialization with new ID
      controller.session[:nothing]
   end
}

4. session pass

We need to pass session ID as parameter when user change domain name, and within domain we still use cookie.

1
“#{request.session_options[:key]}” => request.session_options[:id]

It’s wise to use session initialization before request.session_options[:id] invocation due to Rails use lazy loading, and session can be uninitialized.
Use something like: session[:nothing].

Pay attention that information that Rails get from cookie has bigger priority, and so if you have some parameter in cookie Rails will use it firstly.

Note:
An attacker can still steal you session ID by sniffing the network, or exploiting javascript, he/she gets the value from the cookie itself. If you care about security so much just use HTTPS.

Fast scalability of Ruby on Rails with mongrel under OpenBSD

Wednesday, August 12th, 2009

preamble

Everybody who works with ruby on rails more then month knows at least 2 things:
it’s great framework, but can’t handle multiple requests simultaneously due to it still doesn’t use threads.

fast start

As scalability is common issue, rubyonrails site wiki provides full set of solutions:
[http://wiki.rubyonrails.org/#deployment_stacks]

But we as fast solution will use great OpenBSD pf (Packet Filter) that capable to do many cool things.
First issue is standard mongrail cluster that can start several instances of mongrail can only create them on one IP with different ports, and pf can’t distribute requests among different ports on same IP.

Here we can create 2 simple scripts that start and destroy server instances:
# cat start.sh

1
2
3
4
5
6
7
8
9
10
count=1
for ip in 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5
do
mongrel_rails start -e production -d --user myapp --group myapp --chdir /var/www/railsdocs/myapp \
--address ${ip} \
--pid /var/www/railsdocs/myapp/tmp/pids/mongrel.${count}.pid \
--log /var/www/railsdocs/myapp/log/mongrel.${count}.log

count=$(($count + 1))
done

# cat stop.sh

1
2
3
4
5
for instance in {1..5}
do
mongrel_rails stop --wait 3 --chdir /var/www/railsdocs/myapp \
--pid /var/www/railsdocs/myapp/tmp/pids/mongrel.${instance}.pid
end

And we need to enable pf:
#/etc/rc.conf.local

1
2
pf=YES
#pflogd_flags=                   # add more flags, ie. "-s 256"

add one string to configuration file for load distribution:
#/etc/pf.conf

1
2
rdr pass log on re0 proto tcp from any to SOME_IP port 80 ->
{10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4, 10.0.0.5 } port 3000 round-robin

check work with:
# pfctl -s nat

monitor with:
tcpdump -n -e -ttt -i pflog0

for more info on pf:
http://www.openbsd.org/faq/pf/
man pf.conf (especially ‘TRANSLATION’ and ‘POOL OPTIONS’ sections)

Then when you see you need more advanced solution for load distribution you can install haproxy.
Check it with [http://www.openbsd.org/4.5_packages/i386/haproxy-1.3.15.7.tgz-long.html]

Mozilla Bespin: web-based code editor on web technologies

Friday, February 13th, 2009

Bespin — an experiment from Mozilla Labs that possibly will propose an open, extensible web-based framework for code editing that aims to increase developer productivity, enable compelling user experiences, and promote the use of open standards.

At this time we have initial working experimental prototype that we can use to understand concepts of Bespin and the possibilities that it opens up.
The protorype includes support for basic editing features, such as syntax highlighting, large file sizes, undo/redo, previewing files in the browser, importing/exporting projects.

As for me idea of web-based code editor is arguable due to we have enough excellent standalone open-source code editors like Netbeans [http://www.netbeans.org/] or Eclipse [http://www.eclipse.org/] that have good collaboration possibilities. Standalone code editors we can develop using pretty object-oriented languages like Java and don’t bother with Javascript. But time will say its word.

Mozilla wants you
The Bespin experiment is still in its infancy and just getting started. There are many ways to join the team and get involved: [https://bespin.mozilla.com/]

Firefox 3.0.5: how to fight caching issue

Tuesday, January 20th, 2009

If you are web-developer you probably already heard about regression bug in recent Firefoxes, event latest Firefox 3.0.5 is affected.

Bug is described here on Bugzilla [https://bugzilla.mozilla.org/show_bug.cgi?id=441751], it is fixed, and should be available in new version of Firefox.

As the bug description notes Firefox ignores cache control attributes so we can’t just use them:
Cache-Control: max-age=0, no-store, no-cache, must-revalidate
Expires: Sun, 1 Jan 2000 00:00:00 GMT
Pragma: no-cache

Rare case is you need to tune cache then you can use browser.cache.check_doc_frequency parameter [http://kb.mozillazine.org/Browser.cache.check_doc_frequency] that can be accessed with about:config URL.

But for others question is what to do right now, event with new version of Firefox we can’t ask users to update their Firefoxes.

There are 2 solutions that we have found and tested:

1. If you want to make Firefox to reload some page
You can generate new URLs for any cache sensitive resources every time.
Add some insignificant parameters to URLs: http://www.google.com/something?aaa

2. If you need to make some actions within some page,
for example you need to provide an unique attribute for images in Ads campaign.
You can use Javascript to generate it.
Firefox uses same page but execute Javascript everytime.

You can use following code to generate random number:

1
2
3
4
5
6
7
<script type="text/javascript">
//<![CDATA[

var AdsId = '' + Math.floor(Math.random()*1999999999);

//]]
</script>

I hope men will update their browsers fast so we will not stick with that like with IE6.

RubyConf2008 conference

Tuesday, January 6th, 2009

If you are real Ruby follower you surely know about RubyConf2008 conference that was held in November 2008, or perhaps you even participated. If you still miss all the fun you can go thru whole list of videos from that conference on [http://rubyconf2008.confreaks.com/].

Or at least you can watch videos I’ve selected for busiest men:


name: Reasons behind Ruby
duration: 31 minutes
description: introductory speech from Yukihiro Matsumoto, father of Ruby where he speaks about Ruby, its future, and community in general without any technical stuff.
URL: [http://rubyconf2008.confreaks.com/matzs-keynote.html]


name: Fork Ruby
duration: 48 minutes
description: speech from Dave Thomas that helped write Agile Manifesto, and Programming Ruby: A Pragmatic Programmer’s Guide. He share thoughts about possible ideas for Ruby language and its development.
URL: [http://rubyconf2008.confreaks.com/keynote.html]


name: Ruby 1.9: What to Expect
duration: 50 minutes
description: Dave Thomas and David Black author of popular book Ruby for Rails, Ruby core contributor and the creator and maintainer of RCRchive show to us differences between Rubys with 2 irb windows step by step.
URL: [http://rubyconf2008.confreaks.com/ruby-19-what-to-expect.html]


name: Recovering from Enterprise
duration: 45 minutes
description: Comparison between Ruby and Java worlds from Ruby, and Ruby on Rails contributer Jamis Buck. He describe fundamental differences between Java and Ruby and his mistakes, and ways to avoid them. Also provide ideas how to write in real Ruby and not in Java with Ruby syntax.
URL: [http://rubyconf2008.confreaks.com/recovering-from-enterprise.html]





Next conference will be held on 13-14 March of 2009 in Salt Lake City.
See details on official site: [http://mtnwestrubyconf.org/]


©2010 Helion-Prime Solutions Ltd.
Custom Software Development Agile Company.