MTJ Hax

MiniTest version of RSpec any_instance

Posted in code, ruby, ruby on rails by mtjhax on August 30, 2013

Using MiniTest in Rails apps, I have been missing the RSpec any_instance method:

MyClass.any_instance.stubs(:a_method)

There are other ways to stub in MiniTest but any_instance is convenient and expressive, so I wrote my own quickie version based on aliasing. I call it all_instances to avoid any problems if also using RSpec. Drop this in a file in test/support and make sure it is included in your test_helper.rb:

# this allows a MiniTest test to stub out a method on all instances of a class
# examples:
#
# MyClass.all_instances.stub(:foo, 'bar') do
#   MyClass.new.foo.must_equal 'bar'
# end
#
# MyClass.all_instances.stub(:foo, 'bar')
# MyClass.new.foo.must_equal 'bar'
# MyClass.all_instances.unstub(:foo, 'bar')

class AllInstances
  def initialize(klass)
    @klass = klass
    @@new_method_names ||= {}
  end

  def stub(method_name, return_value)
    @@new_method_names[method_name] = "_original_#{method_name}".to_sym
    @klass.send(:alias_method, @@new_method_names[method_name], method_name)
    @klass.send(:define_method, method_name, ->(*args){ return_value })
    if block_given?
      begin
        yield
      ensure
        unstub(method_name)
      end
    end
  end

  def unstub(method_name)
    @klass.send(:remove_method, method_name)
    @klass.send(:alias_method, method_name, @@new_method_names[method_name])
    @@new_method_names[method_name] = nil
  end
end

class Class
  def all_instances
    AllInstances.new(self)
  end
end
Advertisements

Backboned

Posted in code, javascript by mtjhax on February 26, 2013

Read Backbone’s docs carefully to avoid a fatal security flaw

If you use Backbone.js you are probably “bootstrapping” the data for your models, per their instructions:

Loading Bootstrapped Models
When your app first loads, it’s common to have a set of initial models that you know you’re going to need, in order to render the page. Instead of firing an extra AJAX request to fetch them, a nicer pattern is to have their data already bootstrapped into the page. You can then use reset to populate your collections with the initial data. At DocumentCloud, in the ERB template for the workspace, we do something along these lines:

<script>
  var accounts = new Backbone.Collection;
  accounts.reset(<%= @accounts.to_json %>);
  var projects = new Backbone.Collection;
  projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

 
You have to escape </ within the JSON string, to prevent javascript injection attacks

If you are using Rails 3.x and follow the example code verbatim, you might get something like this in your output:

// var widget = new widgets.model(<%= @widget.to_json %>)
var widget = new widgets.model({ &quot;title&quot; : &quot;&lt;/script&gt;&lt;script&gt;alert('hi')&lt;/script&gt;&quot; });

Obviously, the output is being escaped and .html_safe or raw() needs to be used:

// var widget = new widgets.model(<%= @widget.to_json.html_safe %>)
var widget = new widgets.model({ "title" : "</script><script>alert('hi')</script>" });

Now wait just one second! Some sneaky devil has entered some JavaScript in their title field. You might wonder if this is okay because it’s inside a string — it’s not. If you run this example the alert("hi") code will be executed because the browser’s HTML parser can’t sully itself with understanding JavaScript syntax, so closes the script tag at the very first </script it sees. So by unescaping your output you have created a wide-open security hole exposing your users to XSS attacks.

Maybe you didn’t notice that last line in Bootstrap’s instructions. It’s pretty important.

You have to escape </ within the JSON string, to prevent javascript injection attacks.

I almost fell for this trap before remembering how dangerous html_safe or raw() could be in Rails views, especially in a script section. An old-school trick for breaking up or escaping </script> inside strings is to use "</sc"+"ript>". Ugly hack. There’s an ugly but non-hack way to do it with a CDATA directive. The accepted method, per Backbone’s link, is to simply escape the forward slash character with a backslash: <\/script>.

So you might ask, what is the proper way to do this in Rails? John Firebaugh has a nice writeup of the various alternatives. Some developers have suggested monkeypatching the to_json but this hides the protection from the view and can lead to bad habits. I believe the view code should show explicit evidence of escaping to prevent injection attacks until such escaping becomes a Rails default. Firebaugh ended up suggesting that you replace ActionView::Base#json_escape instead, simply escaping all forward slash characters with blackslashes (gsub('/', '\/')). This is a safe approach because the use of json_escape in views makes the protection explicit.

If you prefer not to overwrite Rails methods to accomplish this task, you could just define a new method such as Object#to_safe_json or ActionView::Base#safe_json. Another way is to use escape_javascript and html_safe together to create a string which is then parsed in JavaScript:

//$.parseJSON('< %= escape_javascript @widget.to_json.html_safe % >')
var widget = new widgets.model($.parseJSON('{\"title\":\"<\/script><script>alert(\'hi\')<\/script>\"}'));

Some developers feel this is inefficient because you have to parse the JSON string, but it makes sense to me — you parse the JSON string returned by every AJAX request, so why not the initial one? This shouldn’t affect your page load performance unless you are bootstrapping a huge Collection, in which case you might want to think about adding some pagination.

Ruby 1.8 strftime works differently on Linux and Windows

Posted in code, ruby, ruby on rails by mtjhax on December 27, 2010

Running Ruby 1.8 on Linux, cygwin, Mac, any POSIX environment:

now = Time.now
=> Mon Dec 27 18:28:28 -0500 2010
now.strftime("%l") # that's a lowercase "L"
=> " 6"

Under Windows using the exact same Ruby version and patch level:

now = Time.now
=> Mon Dec 27 18:28:28 -0500 2010
now.strftime("%l") # that's a lowercase "L"
=> ""

What? It turns out in Ruby 1.8 they cheated by simply calling the standard C strftime() function to implement Ruby’s strftime method. Because different compilers implement strftime() differently, compiling it under Windows results in a different set of supported % directives. Specifically, it looks like under Windows only the basic ANSI C version is implemented, but under POSIX compilers you get a mix of directives defined by ANSI and other standards like Gnu and Single Unix Specification. The “%l” directive was not even listed in the Ruby 1.8 docs — it worked by accident.

The good news is in Rails 1.9 they appear to have implemented their own strftime for consistency, instead of handing it off to the C compiler. If you need to fix this in the meantime, I provide the following monkey patch (which I simply place in my Rails config/initializers folder on any Windows developer machine):

# monkey patch Ruby strftime methods to implement
# %l directive that is missing in Windows Ruby
#
# as a monkey patch, just use this on your Windows
# development boxes to bridge the gap, it's not
# recommended for production
#
# notes:
# - you may want to add support for other missing directives
# - check your RUBY_PLATFORM and make sure it is in the regexp below
#
if RUBY_PLATFORM =~ /mingw32|mingw64|mswin32|mswin64/

  class Time
    alias_method :original_strftime, :strftime
    def strftime(fmt)
      hour12 = "%2d" % ((hour + 11) % 12 + 1)
      original_strftime(fmt.gsub(/%l/, hour12))
    end
  end
 
  class Date
    alias_method :original_strftime, :strftime
    def strftime(fmt)
      hour12 = "%2d" % ((hour + 11) % 12 + 1)
      original_strftime(fmt.gsub(/%l/, hour12))
    end
  end

end
Tagged with: , ,

Rails named_scope gotchas

Posted in ruby on rails by mtjhax on April 29, 2010

There are two terrible gotchas in Rails named_scopes. These two have bitten many a named_scope newbie on the rear (including myself, except that my unit tests caught the problems before they went anywhere but my desktop, w00t for TDD!)

#1. Use length instead of size with the results returned by named_scopes.

Under certain conditions, particularly when using :limit in a named_scope, size and length will return different values. Example:

class Book < ActiveRecord::Base
  named_scope :top, lambda { |limit| {
    :limit => limit,
    :order => 'total_sales DESC'
    }}
end
# imagine we have 10 books with various values for total_sales...
>> Book.top(5).length
=> 5
>> Book.top(5).size
=> 10
# for some reason this only affects named_scopes:
>> Book.find(:all, :limit => 5).length
=> 5
>> Book.find(:all, :limit => 5).size
=> 5
# Go figure!

#2. named_scopes and AR calculations don’t mix

Named scopes are a joy to use, especially when you chain them. It’s completely addictive being able to use constructs like:

topten = Book.fiction.category('vampire').top(10)

(Hypothetical example, I do not read vampire novels…).

The arrays returned by named_scope are ActiveRecord arrays and support calculations such as .count and .maximum, so it’s tempting to want to try something like:

max_fiction_price = Book.top(10).maximum(:price)

Beware! You may not get the results you are looking for — in my experience, these will not work consistently. The problem is that ActiveRecord generates a query something like the following:

SELECT MAX(price) from books ORDER BY price DESC LIMIT 10;

As far as I can tell in researching it, this is not really valid SQL (at least not according to MySQL). LIMIT happens after everything else–similar to HAVING–and only filters the number of output rows that are displayed. Since the MAX() function tells SQL to aggregate the results into a single column, the ORDER and LIMIT clauses are meaningless.

Sometimes this type of statement works for me. I have tried it on SQLite3 and several different versions of MySQL for Linux and Windows. The database sometimes seems to understand that I want to order by price, take the top 10, then calculate the max price. It is entirely possible that in tests where the result appears to be correct, it is actually because the records were randomly ordered in a way that produced the correct result, but purely by chance.

Of course, Rails 3.0 is on the way and there may end up being changes in these behaviors since AR is being rebuilt from the ground up. Whatever the case, avoid mixing conditions and limits, and make sure your unit and functional tests are written to validate the number of results your named_scopes return.

Is soft-delete fail?

Posted in code, ruby on rails by mtjhax on March 1, 2010

Brakeman by artist Will Enns, willenns.com
It appears that the Rails community has hit the brakes hard on soft-delete (marking database records as ‘deleted’ instead of actually deleting them). Is the entire concept of soft-delete fail? Long before the Rails community embraced soft-delete, there were discussions of its various pros and cons.

I’m a big believer in the concept of never permanently deleting data. It’s a pretty easy bandwagon to jump on–why risk losing data when you can safely tuck it away somewhere or simply mark it deleted, then update all of your database queries to ignore the “deleted” rows? As a believer, I’ve worked quite a bit with soft deletion in both web and stand-alone apps, and it has always been an ongoing maintenance headache. Everyone in the organization who touches the data ends up needing to be aware of the soft-deletion scheme to avoid causing problems–programmers, DBAs, even support staff. Even if you move deleted records into a separate table, you are still likely to end up with a system where one forgetful programmer can cause headaches for everyone.

For a while it looked like Rails to the rescue, first with technoweenie’s (Rick Olson) acts_as_paranoid which started as an experiment back in 2005, and more recently semanticart’s (Jeff Chupp) is_paranoid, which cleverly exploited the new ActiveRecord default_scope feature to improve on the concept. Over the years, there has been some criticism of acts_as_paranoid’s problems and limitations but devotees have worked around them. More recently, some plugins and gems have popped up with alternative schemes such as moving deleted records to an archive table instead of marking them as deleted. In the last few months, however, Rails community support for soft deletion seems to be having a meltdown. Jeff of semanticart publicly stated that he is killing is_paranoid and rumored that technoweenie is no longer using acts_as_paranoid. A quick search of the net finds a number of very recent articles slamming soft-delete in general (for example, see Luke Francl’s list of softdelete Bookmarks) and there are an increasing number of Rails add-ons dedicated to the concept of moving deleted records to an archive table.

Ultimately, the argument for killing is_paranoid boiled down to how making soft-delete transparent added one too many layers of Rails magic, shielding the programmer from important data considerations that should have been kept explicit. Soft-delete doesn’t get off the hook that easily though–it still presented problems even when wrapped in Rails magic. For example, you can get into trouble if you use unique indexes in your database. Imagine a row is soft-deleted, then you try to create a new row with the same attributes that were supposed to be unique. Also, as Rails has rapidly evolved new and interesting methods of associating and finding data, the soft-delete add-ons required constant updating.

Personally, I’m starting to think the best answer is to remove all consideration of soft-delete / archive-delete from your apps and handle this externally. There are quite a few tools out there for backing up data in real-time as it is created, using SQL triggers so deleted rows are automatically journaled or moved into an archive, etc. There are also some pretty compelling articles asking an important meta-question, why are we deleting data at all?

For further reading with some interesting suggestions for alternatives, I recommend Luke Francl’s post on Rail Spikes.

If you use Rails, take a few minutes to learn Ruby

Posted in ruby on rails by mtjhax on February 9, 2010

I’m sure I’m not the first person to code three or four complete Ruby on Rails projects before bothering to learn the finer points of Ruby, but after looking at some old code I’ve gotta say I wish I had spent a day just reading Pickaxe or Why’s (poignant) Guide before I jumped in with both feet.

There are dozens of examples of my former Ruby stupidity in virtually any module on my hard disk. They mostly fall into the category of “doing things the C++ way instead of learning the Ruby way”. For example:

  if !my_param.nil? && my_param.is_a?(Integer) && my_param >= 0 && my_param < 10
    # do stuff
  end

Tsk tsk. Terrible mess. Imagine an entire module full of that. The following is just so much better:

  if (0..9).include?(my_param)
    # do stuff
  end

This one method properly deals with nil and non-integer values. Nice!

Of course, I don’t blame C++ for my cluttered code — one could easily create their own syntactic sugar in C++ for common tasks like parameter-checking. The point is that Ruby has all these cute tricks already, and you should be making your life easier by using them!

If you happen by this post, I invite you to share your own favorite Ruby tricks.

Tagged with: , ,

Restart your Phusion Passenger app from a web page

Posted in ruby on rails, web hosting by mtjhax on February 2, 2010

Phusion Passenger has a cute way of letting you restart your Rails app instead of restarting your web server. You just create or touch the file myapp/tmp/restart.txt. If you want to do this from inside your Rails app (maybe you’re tired of typing ‘touch tmp/restart.txt’ in a SSH prompt) just do something like this in a controller:

def restart_server
  FileUtils.touch(File.join(RAILS_ROOT,'tmp','restart.txt'))
  render :nothing => true
end

Just make absolutely certain that this action is not accessible from the outside world (administrators only), can’t be invoked accidentally by a redirect (put in a confirmation dialog?), and can’t get involved in any sort of infinite loop (don’t put anything like this in a homepage controller action). Obviously it doesn’t have to be in a controller, but when you’re sawing off the tree branch you are sitting on, it’s nice to be near the ground (i.e., closer to the top of the call stack).

Administrating restful-authentication users with ActiveScaffold

Posted in ruby on rails by mtjhax on January 16, 2010

Needing a quick set of admin pages for a site that uses Restful-authentication, I decided to use one of the many nifty scaffolding tools for Ruby on Rails to generate some customizable views. I settled on ActiveScaffold for reasons I will mention later.

The normal way you use ActiveScaffold is to simply add an ‘active_scaffold’ declaration to your controller that causes views to be dynamically generated. For example:

class UsersController < ApplicationController
  active_scaffold
end

The problem is that this code adds actions such as show, list, and create to your controller that are almost certainly already in use by your user-facing web site. The obvious answer is to create a separate controller and configure ActiveScaffold to  specify which model to use. Easy enough, but there are a couple useful tricks worth considering.

Why ActiveScaffold?

ActiveScaffold caught my eye for a number of reasons including the fact that their main page has links directly to their competition in case “ActiveScaffold isn’t what you’re looking for”. I’m not sure if that’s a friendly open-source attitude or a bit of a boast–maybe a little of both–it’s all good either way. Hobo and Streamlined both looked really cool but were a bigger investment in learning curve than I cared to make that afternoon. Lightweight is always good when patching stuff on to an existing site and refactoring isn’t in the budget.

An interesting feature of ActiveScaffold is that the views are dynamically generated and customized through configuration options, helpers, and CSS (as opposed to code being emitted and then customized directly). There seems to be a minor movement in some Rails circles away from code generators towards configurable, customizable plugins/gems. Another example is authlogic, the hot new flavor for user authentication in Rails. This all seems a little contrary to Rails doctrine (convention over configuration) but the configuration is lightweight and it reduces the amount of cruft I have to add to my code that is tangential to my application’s purpose. For a plugin that makes a ton of sense.

Approaches

One interesting approach to make a user admin interface is to use the map.namespace feature in routes.rb. With this you can create restful routes such as /admin_users, /new_admin_users, /delete_admin_users, etc. Something like this:

map.namespace :admin do |admin|
    admin.resources :users
end

Then you can create new admin controllers and views in app/controllers/admin, app/views/admin/users, etc. This is a great pattern but it’s a little tricky to implement with something like ActiveScaffold that is automatically generating your views.

The simpler approach with ActiveScaffold is to simply create a new controller, say AdminUsersController, and specify the model name in your active_scaffold configuration:

active_scaffold :<your_model_name>

There’s only one hitch. Everyone in Rails these days is pushing the “thin controller, fat model” doctrine. What happens when you need special logic only available to administrators? Obviously you can add to your controller, but you might not be able to access everything in your model to provide this special behavior without opening some potential security holes. The best way for me turned out to be subclassing the User model as well as creating a new controller.

Implementation

In my case, I wanted to automatically activate users that are created by the admin without sending activation emails.

Step 1, subclass your normal Users model in models/user.rb:

# model subclass only used by admin backend
class AdminViewUser < User
  # override method instead of using callback macro to prevent super from being called
  def before_create
    auto_activate
  end
  # (optional) skip post-activation email for users created by admin
  def recently_activated?
    false
  end
protected
  def auto_activate
    @created = false  # (optional) skip sending signup email for users created by admin
    self.activated_at = Time.now.utc
    self.activation_code = nil
  end
end

Step 2, modify models/user_observer.rb to checks for automatic activation before sending out emails (optional):

class UserObserver < ActiveRecord::Observer
  def after_create(user)
    UserMailer.deliver_signup_notification(user) if user.recently_created?
  end
  def after_save(user)
    UserMailer.deliver_activation(user) if user.recently_activated?
  end
end

Step 3, add a new controller that uses ActiveScaffold, restricted to admin users only, in controllers/admin_view_user_controller.rb:

class AdminViewUserController < ApplicationController
  before_filter :admin_required  # see authenticated_system.rb below
  active_scaffold do |config|
    config.label = "My Fancy User Admin Page"
    config.columns = [:login, :email, :password, :password_confirmation, :created_at, :updated_at]
    # exclude some columns from specific views, for more config options see ActiveScaffold web site
    list.columns.exclude :password, :password_confirmation
    show.columns.exclude :password, :password_confirmation
    update.columns.exclude :created_at, :updated_at
    create.columns.exclude :created_at, :updated_at
  end
end

Final step, implement the :admin_required method. I added a column called ‘is_admin’ to my users table and created some new methods in lib/authenticated_system.rb:

module AuthenticatedSystem
  protected
  def is_admin?
    logged_in? && current_user.is_admin?
  end
  def admin_required
    is_admin? || access_denied
  end
end

This is just an example to get you started. There are probably security enhancements that could be made and, obviously, you can administrate models other than just User. In my version I also added a UserGroup model that is also administrated by ActiveScaffold.

Comatose CMS for Ruby on Rails

Posted in ruby on rails by mtjhax on December 20, 2009

Anyone who has built a Rails app and wanted to use a CMS just for the static portions of the site knows that there is no easy solution, especially when the CMS and Rails app need to share things like user logins. This issue is well-described by Aaron Longwell in his June ’09 blog post, The Ruby on Rails CMS Dilemma.

I started playing with different Ruby on Rails CMS offerings to learn more and try to come up with some new approaches. One really interesting little project popped up called Comatose CMS, initially developed by cartoonist/programmer Matt McCray. Comatose has a couple of sweet features I feel like every CMS should have:

  • Comatose runs as a loosely-coupled plugin to your Rails app (as opposed to being the base upon which you need to layer your app). If you want Comatose to generate a page, you just route the request to Comatose with some entries in your routes.rb file. If you want your app to handle the request, route it normally. Simple!
  • Comatose pages can be rendered inline similar to Rails partials. Imagine you have an entire app already built and you need a quick way to allow someone to edit specific chunks of content without moving entire pages into your CMS. Comatose inline rendering could have you there literally in minutes.
  • Comatose can use the same layouts as your regular app.
  • Comatose uses a simple callback pattern to use your app’s authentication and access control as its own. You can configure Comatose to mix-in any modules it needs (like the restful-authentication lib), then set up callback procs to control access to both the generated pages and the back-end editing interface.

I guess the main drawback to Comatose is that the original author has not worked on it recently and the two or three other committers have not made any changes in nearly a year. It does work with the latest Rails 2.x though. With more activity you might see better documentation, more examples and design patterns, maybe a few new features. Also, with a project this inactive, one worries that there are security flaws, performance issues, or other difficulties yet to be discovered. Unless I find another CMS with similar features, I’m thinking of giving it a go in a real project and seeing what I run into.

 

UPDATE October 2010: I realized that there is one major drawback to working with this CMS at this point — it was written to use an older, obsolete version of the Liquid markup language that is embedded into the app. If you install a more recent version of the Liquid GEM for any reason (I tried 2.0.0 and 2.2.2) it will cause Comatose to crash. Of course, someone with a little more free time than I have could fork the Comatose project and update it to use the latest version of Liquid, but this project is looking pretty dead. I guess full-fledged CMS apps like Radiant have officially won the day. Shame there isn’t more interest in this type of hybrid solution.

 

Here are a few Comatose CMS tips:

 

By arranging your routes in different ways, you can have Comatose handle everything, only specific pages, or any page not otherwise explicitly routed. I prefer that last style — just use resource maps and named routes for everything in your app, remove the default :controller/:action/:id routes, and add something like map.comatose_root "" at the end. For example:

map.resources :users
map.resource :profile
map.comatose_admin
map.comatose_root '', :layout => 'application'

A request for anything except /users or /profile will fall through to the CMS. If the CMS cannot find the request page it will render it’s own “404 not found” page (which you define by creating a page called “404” at the top level of your page heirarchy).

 


 

Comatose routes can be used like named routes in the app. For example, one might link to an /about page with comatose_root_path(:about). Sub-pages in the heirarchy can be accessed one of two ways, with an array of strings or symbols, or a string argument to the helper: comatose_root_path([:legal, :privacy]), or comatose_root_path('legal/privacy').

 


 

If you don’t like the look of comatose_root_path(:about) and comatose_root_url(:about) as helpers, you can make a shorter route such as:

map.static ':page', :controller => 'comatose', :action => 'show'

Then use static_path(:about) and static_url(:about) instead. The only drawback to this approach is that sub-pages will end up with ‘%2F’ (the entity for ‘/’) in your browser’s address bar.

To cause errors to be generated instead of 404 pages (maybe useful for debugging during development?) you could limit the possible values for :page as follows:

map.static ':page', :controller => 'comatose', :action => 'show', :page => /about|help|contact|legal\/privacy|legal\/terms/

 


 

For Comatose to use your app’s layouts, any helpers or modules used by the layout need to be included in the Comatose controller since it doesn’t inherit ApplicationController. This is easily configured in environment.rb:

Comatose.configure do |config|
config.helpers << :layout_helper    # my layout helpers
config.includes << :current_user  # my module that includes a current_user method

 


 

Finally, here’s some code for a layout that provides an “Edit this page” link for anyone who is logged in as an administrator:

<% if current_user && current_user.is_admin? && @page && @page.is_a?(Comatose::PageWrapper) %>
<%= link_to("Edit this page", "/comatose_admin/edit/#{@page['id']}") %>
<% end %>

Notice that @page is defined in the layout when Comatose is handling a page. It contains all sorts of useful information to take advantage of in your layout.

Tagged with: , , ,

Hosting your app on GoDaddy from the site root

Posted in web hosting by mtjhax on November 6, 2009

A quick tip for those who are hosting a Rails app (or any app really) on GoDaddy or other shared hosting sites where the app ends up being hosted from a subdirectory, e.g. http://www.mysite.com/my_app/ instead of just http://www.mysite.com.

If you only have one application and want it to be hosted from your root URL, edit your top-level .htaccess file (where you see default GoDaddy files like welcome.html and missing.html) and add something like the following:

# EDIT: added first line so GoDaddy web stats won't break!
# if the requested URL doesn't start with /stats/ or /my_app/
# then add /my_app/ to the beginning
RewriteCond %{REQUEST_URI} !^/stats/.*
RewriteCond %{REQUEST_URI} !^/my_app/.*
RewriteRule ^(.*)$ /my_app/$1

If you are using Rails, you can now get rid of the relative_url_root configuration (usually in environment.rb or production.rb), so links will be generated like /images/mypic.jpg instead of /my_app/images/mypic.jpg (although both should work fine).

This probably works on other Apache-based shared hosting providers as well. I haven’t road-tested this solution completely but it’s very basic Apache stuff so there shouldn’t be any problems.

EDIT: Here’s an even better tip for those who are thinking of hosting a Rails app on GoDaddy shared hosting… don’t do it! Unless you just need a cheap site for sharing prototypes. You can get decent VPS hosting for $15/month these days–there’s no reason to have a slow site running on outdated Apache & FastCGI versions that mysteriously crashes about one out of ten page views just to save $7 a month. In GoDaddy’s defense, shared hosting is a fail concept of bygone days now that VPS technology has become so widespread and inexpensive–there’s nothing particularly wrong with their service that a few version updates wouldnt fix.