659 snippets – displaying 1–30

Ruby's call method

rubycallchristianVersion 3

What does this print:

class RubyCall
  def call(*args)
    puts "Call: #{args}"

xxx = RubyCall.new
xxx.("hello", 1, 2, 3)

It calls the #call method and prints “Call: [”hello", 1, 2, 3]".

If you want to spice up your Ruby-life you can do this:


How to record and replay TCP traffic

tcpreplaychristianVersion 2

First attempt

1) Record TCP traffic with tcpdump to pcap file

Record traffic on ethic from host and port 2332, write to app-traffic.pcap:

tcpdump -vvv -i eth0 host and port 2332 -w app-traffic.pcap &

2) View captured traffic

tcpdump -qns 0 -X -r app-traffic.pcap

Edit captured traffic if needed with Wireshark.

3) Edit source IP so that it’s on your own network

See the ”example in tcprewrite documentation”:http://tcpreplay.synfin.net/wiki/tcprewrite for details on how to rewrite source IP:

$ tcprewrite --pnat=, --infile=input.pcap --outfile=output.pcap --skipbroadcast

4) Replay traffic with tcplivereplay from recorded pcap file (note step #3)

”See tcpliveplay documentation”:http://tcpreplay.synfin.net/wiki/tcpliveplay for details.

Note that tcpliveplay is only available on Linux not OSX.

Second attempt


sudo tcpdump -i en0 host and port 2332 -w app-traffic.pcap


tcpdump -s 0 -n -e -x -vvv -r app-traffic.pcap


sudo tcpreplay -i en0 -t -K app-traffic.pcap

Or use tcplivereplay (Note: Linux only):


I couldn’t get it to work….

Big Search Field & Button = Beautiful?

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css"/>

.search-form {
  width: 40%;
  min-width: 400px;
  border: 6px solid rgba(0, 0, 0, 0.7);
  margin: 20px auto 0;

input.text {
  float: left;
  width: 80%;
  border: 5px solid #fff;
  margin: 0;
  outline: none;
  font-size: 17px;
  -webkit-border-radius: 0;
  -moz-border-radius: 0;
  -ms-border-radius: 0;
  -o-border-radius: 0;
  border-radius: 0;
  -webkit-appearance: none;
  color: #3c3c3c;

input.text, input.button {
  padding: 15px;
  font-size: 17px;
  font-weight: 800;
  display: inline-block;
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
  transition: all 0.3s ease;

input.button {
  float: right;
  width: 20%;
  margin: 0;
  border: 5px solid grey;
  color: #fff;
  background-color: grey;
  -webkit-appearance: none;
  padding-left: 0;
  padding-right: 0;
  -webkit-border-radius: 0;
  -moz-border-radius: 0;
  -ms-border-radius: 0;
  -o-border-radius: 0;
  border-radius: 0;

.clearfix {
  overflow: auto;

* {
  font-family: "Helvetica", sans-serif;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  <div class="search-form clearfix">
    <input name="query" class="text" type="text" placeholder="Find your dog&hellip;">
    <input type="submit" value="Search" class="button">

Eventmachine Echo Server Example

require 'rubygems'
require 'eventmachine'
require 'logger'

# Each connection creates a new EchoServer.
module EchoServer
  LOG = Logger.new('echo.log')

  # Called by the event loop immediately after the network connection has been
  # established, and before resumption of the network loop.
  def post_init
    LOG.info "-- Connection established #{remote_ip} --"

  # Called by the event loop whenever data has been received by the network
  # connection. It is never called by user code.
  def receive_data data
    message = "#{remote_ip}: #{data}"
    LOG.info message
    send_data message
    close_connection if data =~ /quit/i

  # Called by the framework whenever a connection (either a server or client
  # connection) is closed.
  def unbind
    LOG.info "-- Connection closed #{remote_ip} --"

  # Return the IP and port of the remote client.
  def remote_ip
    @remote_ip ||= begin
                     port, ip = Socket.unpack_sockaddr_in(get_peername)

EventMachine::run do
  Signal.trap("INT")  { EventMachine.stop }
  Signal.trap("TERM") { EventMachine.stop }
  EventMachine::start_server "", 8080, EchoServer

Use telnet to test it:

$ telnet localhost 8080

Daemonization Best-Practices

Don’t daemonize your daemons


What’s the result? In development mode, your process will run in the foreground, as yourself and log to stdout: perfect for developers. In production mode, the init system will run your process as a configured user with logging sent to a specific location and log rotated automatically. Less system administration, easier debugging, simpler code, all because you leveraged the init system to do the work for you!</quote>

Running processes


Note: In every case, it’s assumed that you have a program that wants to run that does not daemonize on its own. Self-daemonizing programs start you down the path to hell. You can’t use any sane keepalive techniques so you have to resort to polling process lists or checking the pid or something. Even managing that pidfile gets hard when you combine it with things that change their own uid for safety (because you should never run anything as root).</quote>

Ubuntu, upstart, and creating a pid for monitoring


If start-stop-daemon is available on your machine, I would highly recommend using it to launch your process. start-stop-daemon will handle launching the process as an unprivileged user without forking from sudo or su (recommended in the upstart cookbook) AND it also has built in support for pid file management.</quote>



Foreman is a manager for Procfile-based applications. Its aim is to abstract away the details of the Procfile format, and allow you to either run your application directly or export it to some other process management format.</quote>

How to introduce Rubocop in your project


Edit Gemfile:

group :development do
  gem 'rubocop' # Style guide checker
  gem 'guard-rubocop' # Rubocop plugin for Guard


$ bundle


Run Rubocop:

$ rubocop --auto-gen-config


Edit .rubocop.yml:

inherit_from: .rubocop_todo.yml

Introduce new rules gradually in priority order by enabling and moving rules from .rubocop_todo.yml to .rubocop.yml.

You can also use the Ruby style-guide’s rubocop configuration:

Workflow integration


$ guard init rubocop

Edit Guardfile:

guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '--rails'] do
  watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }

Editor Integration

Optionally, integrate Rubocop with your editor:

CI integration

See How to introduce rubocop and integrate into Jenkins.

How to parse a cronline/crontab/cron with Ruby

You can use the rufus-scheduler gem to parse cronline/crontab/cron with Ruby.


gem 'rufus-scheduler'


require 'rufus/scheduler/cronline'
cron = Rufus::Scheduler::CronLine.new("00 00 1 * *") # 00:00 every first day of the month
next_time = cron.next_time(Time.current)
previous_time = cron.previous_time(Time.current)

rufus-scheduler’s cronline implementation:

See tests for details and syntax:

Cron configuration examples.

Playing with Ruby and Rails Time and Time Zones


What you need to know to handle date and time correctly in Ruby and Rails is, at least:

  • the input’s time zone when parsing time and date.
  • the user’s time zone when calculating time and date in his/her time zone.
  • Ruby and Rails date and time handling. Use Time.current and Time.zone (Rails) to avoid using the computer’s time zone (Ruby).

Things to remember

  • Is the given time in the user’s time zone (Time.zone.local) or in UTC (Time.zone.utc)?
  • The correct time zone is needed when you’re accessing date components like e.g. year, month, day, hour, start of day, start of month, etc
  • Rails takes care of time and date handling inside the application. It’s when you accept input or want to output data that you need to tread carefully.
  • Cache carefully. Maybe you need to display date and time using JavaScripts.
  • Daylight savings, plus some countries or states don’t even have DST, but might have had 100 years ago…
  • The difference between e.g. Time.now and Time.current.
  • Possible timezones: application, user, server, and database timezone
  • APIs should output ISO-8601

require 'tzinfo'
tokyo = TZInfo::Timezone.get('Asia/Tokyo')

# When it's 12:00 in Tokyo, what hour is it in UTC?
time = tokyo.local_to_utc Time.local(2014, 01, 01, 12, 00) # => 2014-01-01 03:00:00 UTC
utc_hour = time.hour # => 3
utc_time = time.utc # => 2014-01-01 03:00:00 UTC

# When it's 12:00 in UTC, what hour is it in Tokyo?
time = tokyo.utc_to_local Time.local(2014, 01, 01, 12, 00) # => 2014-01-01 21:00:00 UTC
tokyo_hour = time.hour # => 21
tokyo_time = tokyo.local_to_utc(time) # => 2014-01-01 12:00:00 UTC

# Convert Tokyo time to local time, i.e. convert user's local time to our local time
tokyo.now # => Tue, 18 Nov 2014 03:02:28 JST +09:00
tokyo.now.utc # => 2014-11-17 18:04:20 UTC
# local_to_utc => -0900
tokyo.local_to_utc tokyo.now # => 2014-11-17 18:03:02 UTC
# utc_to_local => +0900
tokyo.utc_to_local tokyo.now # => 2014-11-18 12:03:17 UTC
Time.parse Time.find_zone!('Tokyo').now.to_s

# Parse input from Helsinki and input from Stockholm when input contains no time zone information
a = Time.find_zone!('Helsinki').parse('201411121415')
b = Time.find_zone!('Stockholm').parse('201411121315')
a == b

a = Time.use_zone 'Helsinki' do
b = Time.use_zone 'Stockholm' do
a == b # OK

# Using the tzinfo library directly
zone = TZInfo::Timezone.get('Africa/Harare')

# Rails time zones

# Daylight savings, anyone?
tokyo = TZInfo::Timezone.get('Asia/Tokyo')
tokyo.current_period.utc_offset # Doesn't include DST
tokyo.current_period.utc_total_offset # Includes DST

Time.use_zone 'Helsinki' do
  Time.local(2014, 10, 26).dst? # => true
  Time.local(2014, 10, 27).dst? # => false

Time.use_zone 'Pacific Time (US & Canada)' do
  # 00:00 01.06.2014 in Los Angeles, during DST
  now = Time.zone.local(2014, 6, 1)
  puts now.dst? # => true
  offset = now.utc_offset
  puts offset / 1.hour # => -7
  # 00:00 01.12.2014 in Los Angeles, after DST
  now = Time.zone.local(2014, 12, 1)
  puts now.dst? # => false
  offset = now.utc_offset
  puts offset / 1.hour # => -8

# Beginning of day in other time zone
Time.use_zone 'Hawaii' do
  now = Time.local(2014, 10, 27)
  puts now.beginning_of_day.dst? # false, Hawaii doesn't follow DST although the rest of the U.S.A. does.
  puts now.beginning_of_day.utc # => 2014-10-26 22:00:00 UTC
  puts now.beginning_of_day # => 2014-10-27 00:00:00 +0200

# Misc stuff

Time.now.formatted_offset # => "+02:00"

def without_timezone
  times = [

  times.each do |time|
    puts times[0].to_i == time.to_i # All OK

def with_timezone
  times = nil
  Time.use_zone('Tokyo') do
    times = [
  Time.use_zone('Stockholm') do
    times.each do |time|
      puts times[0].to_i == time.to_i # All OK

def parse_time
  times = nil
  time = '201411121415'
  Time.use_zone('Tokyo') do
    times = [
      Time.zone.parse(time).in_time_zone, # ERROR: 7 hour time difference
      Time.zone.parse(time) # ERROR: 7 hour time difference
  Time.use_zone('Stockholm') do
    times.each do |time|
      binding.pry unless times[0].to_i == time.to_i


Also see Working with time zones in Ruby on Rails.

How to run only one specific test with Rspec

Focusing on one or more tests with Rspec

You can tell Rspec to run only tests tagged with “focus: true” by running Rspec with the —tag focus switch:

rspec ./spec/controllers/concerns/session_expiry_spec.rb --tag focus

This would run e.g. only this test which is marked with “focus: true”:

it "resets session if session has expired", focus: true do

Integrating with Guard

Use this configuration to integrate this workflow with Guard:

guard 'rspec', cli: '--tag focus --format d --color', all_after_pass: false, all_on_start: false do

We also want to run all tests when there are no focused tests. We therefore add this to spec/spec_helper.rb:

RSpec.configure do |config|
  # This is dangerous with CI integration e.g. Jenkins
  # config.filter_run focus: true
  config.run_all_when_everything_filtered = true

Rspec configuration file

One alternative is to enable the focus option in the Rspec configuration file:

RSpec.configure do |config|
  config.filter_run :focus => true
  config.run_all_when_everything_filtered = true

However, this would be dangerous when running tests with e.g. Jenkins and when someone forgets to remove “focus: true”.

I18n for ActiveRecord Model Attributes

This code will translate the AR model’s title attribute using Rails’ I18n library:

class Link < ActiveRecord::Base
  I18N_ATTRIBUTES = [ :title ]
  I18N_ATTRIBUTES.each do |attr|
    class_eval <<-EORUBY, __FILE__, __LINE__ + 1
      def #{attr}
        I18n.t(self[:#{attr}], default: self[:#{attr}])

If a translation is not defined, the code will fall back to use the attribute’s original value.

Example with translation defined:

Translation file (config/locales/en.yml):

      title: Hello

Model code (app/models/link.rb):

link.title = 'views.index.title'
# Uses string from config/locales/en.yml
link.title => "Hello"

Example without translation defined

link = Link.new title: 'Hello'
# Fall back to specified value, because no translation is defined
link.title => "Hello"

How to draw centered text on an HTML canvas

Draw centered text on an HTML canvas:

canvas = ...
// Device dependent pixel ratio, also changes when zooming
pixelRatio = window.devicePixelRatio || 1
// Centered text
ctx.textAlign = "center"
ctx.textBaseline = "middle"
// Font size
fontSize = 20
// Adaptive bold font
ctx.font = 'bold ' + Math.round(fontSize/pixelRatio) + 'px Oswald'
// Measure text width
textRect = ctx.measureText(text)
// Figure out where to position the text
x = (canvas.width / 2) / pixelRatio
y = ((canvas.height / 2) - (fontSize*2)) / pixelRatio
// Draw the text
ctx.fillText("Hello world" , x, y)

The code adapts the font size and text position to fit the selected zoom level (e.g. 200%) and the current device (e.g. mobile).

How to Use the JSON and HStore Postgres Data Types With Rails 4

First enable the hstore Postgres extension. In this example we define both a JSON and an HStore column:

class Schema < ActiveRecord::Migration
  def change
    enable_extension "hstore"
    create_table :links do |t|
      t.hstore :data
      t.column :settings, :json

Next, we specify accessors for the data that we will be stored in the JSON and HStore columns:

class Link < ActiveRecord::Base
  # Use hstore for text-only data:
  store :data, :name, :url, :description
  # Use JSON to support string, number, object, array, true, false, null
  store :settings, :update_interval, :created_at, :updated_at

We can now use the defined ActiveRecord attributes to store and access JSON and HStore data:

Link.create! name: 'Google', url: 'http://google.com', description: 'Ad company', update_interval: 1.day, created_at: Time.now.utc

Querying the data is where you’ll see the biggest differences. Two examples:

# hstore
Link.where("data -> 'name' = ?", 'Google')
# json
Link.where("CAST(settings->>'update_interval' as integer) = ?", 1.day.to_s)

Notes for Postgres 9.3:

  • HStore can store only text. Nested data is not supported.
  • JSON supports the following types: string, number, object, array, true, false, null. For example, date and time types are not supported. Nested data is supported.

Rails prepend_view_path


class ApplicationController < ActionController::Base
  prepend_view_path 'x/y/z/views'


# config/initializer/view_path.rb
ApplicationController.prepend_view_path 'x/y/z/views'

In development mode (Rails 3.x) this doesn’t seem to work under some circumstances, i.e. the prepended path is lost after Rails’ reloads after you modify certain files.

How to Use Rails I18n With JavaScript/CoffeeScript

Option 1: Include all translations

Your app/assets/javascripts/i18n.js.coffee.erb file:

root = exports ? this
I18n = <%= I18n.backend.send(:translations).to_json.html_safe %>
$ ->
  root.I18n = I18n[$('body').data('lang')]

Option 2: Include a limited set of translations

Your app/assets/javascripts/i18n.js.coffee.erb file:

root = exports ? this

I18n =
I18n.available_locales.each do |lang|
  I18n.with_locale lang do
  <%= lang %>:
    text: "<%= I18n.t("js.text") %>"

$ ->
  root.I18n = I18n[$('body').data('lang')]

Include the Selected Locale in the Rails Layout

The view defines the user’s selected locale:

<body data-lang="<%= I18n.locale %>">

How to Translate JavaScript Strings

We can now translate strings in a JavaScript file:

# remember to use $(document).ready...

How to Create and Configure a Static Website Hosted on Amazon S3

This will create two S3 buckets and configure them for hosting a static website:

aws s3 mb s3://xxx.com
aws s3 mb s3://www.xxx.com

aws s3api put-bucket-website --bucket www.xxx.com --website-configuration '{
    "RedirectAllRequestsTo": {
        "HostName": "xxx.com"

aws s3api put-bucket-website --bucket xxx.com --website-configuration '{
    "IndexDocument": {
        "Suffix": "index.html"
    "ErrorDocument": {
        "Key": "404/index.html"

aws s3api get-bucket-website --bucket www.xxx.com
aws s3api get-bucket-website --bucket xxx.com

Next, allow anyone to access the files:

aws s3api put-bucket-policy --bucket www.xxx.com --policy '{
  "Version": "2012-10-17",
  "Statement": [
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::www.xxx.com/*"

Next, upload your website to S3:

aws s3 sync build s3://www.xxx.com --acl public-read --delete

In the above example all files are located in a folder named build.

Done. Your website can be found at http://<bucket name>.s3.amazonaws.com/index.html.


  • if you’re serious about hosting your website, use AWS Cloudfront or Cloudflare + S3
  • the “www” URL redirects to the “non-www” URL

Automatic Instantiation of Web Components Written in JavaScript/Coffeescript

componentschristianVersion 9

Your app.js.coffee:

$ ->
  for component in $('.web-component')
    component = $(component)
    class_name = component.data('class')
    id = "#" + component.attr('id')
    component_class = eval.call(window, class_name)
    if component_class
      console.debug("Creating #{class_name}")
        new component_class(id)
      catch error
        console.log "Failed to create #{class_name}"
      throw "UI component '#{class_name}' does not exist."

Declare a web component in your view:

<div id="alerts" class="web-component" data-class="App.Alerts"/>

Write your web component, e.g. app/assets/javascripts/components/alert.js.coffee:

root = exports ? this
# declared elsewhere
# root.App = {}

class Alerts

root.App.Alerts = Alerts

Render Rabl Views Anywhere (views, jobs, mails)

A helper for rendering Rabl views anywhere, e.g. background jobs, views, mails, etc:

def render_rabl(locals, view, options = {})
  scope = Object.new
  locals.each do |key, value|
    scope.instance_variable_set :"@#{key}", value
  options = { format: :json, scope: scope }.merge(options)
  Rabl.render(nil, view, options)


locals = { users: User.all }
view = 'users/index'
render_rabl locals, view

A Reusable JavaScript Modal Dialog Based on Bootstrap Modal

The Coffeescript class:

root = exports ? this

class Modal
  constructor: (options = {}) ->
    @options = options
    @id = options.id ? 'modal-dialog-' + Math.round((Math.random() * 1000))
    @dom_id = "##{@id}"
    @onPrimaryButton = options.onPrimaryButton ? ->
    @onSecondaryButton = options.onSecondaryButton ? ->
    @template = options.template ? HandlebarsTemplates['modal'](id: @id)

  render: ->
    @modal = $(@dom_id)
    _this = this
    @modal.find('.btn-primary').on 'click', ->
    @modal.find('.btn-secondary').on 'click', ->

  setButtonText: (primary, secondary) ->

  setTitle: (title) ->

  setBody: (body) ->

  show: ->

  hide: ->

root.Modal = Modal

The view (bootstrap 2.3.2):

<div class="modal hide fade" id="{{id}}">
  <div class="modal-header">
    <button aria-hidden="true" class="close" data-dismiss="modal" type="button"> &times;</button>
    <h3 class="title"></h3>
  <div class="modal-body body">
  <div class="modal-footer">
    <button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
    <button class="btn btn-primary" data-dismiss="modal">Ok</button>

Usage, e.g.:

class Notifications
  constructor:  ->
    @modal = new Modal
      onPrimaryButton: $.proxy(@onItemDelete, this)
      onSecondaryButton: $.proxy(@onItemRead, this)
  onItemDelete: ->
    # do something when primary button was clicked
  onItemRead: ->
    # do something when secondary button was clicked

Selecting a JavaScript Chart Library

Which JavaScript library should I use for generating charts? Here’s a list of popular JavaScript libraries for generating charts. Remember to check the license before selecting one…



  • based on D3.js
  • +3000 followers on Github
  • +150 issues on Github


  • +30 000 followers on Github
  • +150 issues on Github
  • unlimited possibilities
  • unlimited complexity
  • unlimited popularity
  • you need to write your own reusable d3.js components
  • supports Firefox, Chrome, Safari, Opera, IE9+, Android and iOS. Parts of D3 may work in older browsers.


  • based on D3.js
  • +3000 followers on Github
  • +250 issues on Github


  • based on D3.js
  • +900 followers on Github
  • +30 issues on Github


  • 3500 Github followers
  • 30 Github issues


  • 4000 Github followers
  • 10 Github issues


  • 1500 Github followers
  • 30 Github issues
  • based on D3.js


  • Works with Internet Explorer 6+, Chrome, Firefox 2+, Safari 3+ and Opera 9.5+
  • requires jQuery
  • +3500 followers on Github
  • +250 issues on Github


  • +1400 followers on Github
  • +110 issues on Github
  • supports Firefox 3.0+, Safari 3.0+, Opera 9.5+ and Internet Explorer 6.0+.


  • “23 000 customers”
  • price is “as much as you can pay”


  • Free for non-commercial projects
  • HTML5
  • “tens of thousands of developers”
  • supports line, spline, area, areaspline, column, bar, pie, scatter, angular gauges, arearange, areasplinerange, columnrange and polar chart


  • Uses Google charts behind the scenes


  • Based on d3.js
  • 385 followers on Github
  • 18 issues on Github
  • “optimized for visualizing and laying out time-series data”

Getting Started With React.js and Rails

Why use React.js?

  • React ~35kb vs. Amber.js ~100kb
  • Easy to learn compared to Ember.js and Angular.js
  • Supports server-side rendering
  • Great performance
  • Angular.js documentation is horrible
  • Angular.js is the new EJB?

Why shouldn’t you use React.js?

  • React.js is difficult to integrate with JS libraries that move or create DOM elements, e.g. jQuery UI
  • React.js is still evolving. Expect API changes to break your app.



gem 'active_model_serializers' # You probably want this gem too...
gem 'react-rails', '~> 1.0.0.pre', github: 'reactjs/react-rails'

From the console run:

rails g react:install

Make sure you have this in app/assets/javascript/application.js:

# ...
#= require react
# For the <div data-react-class...> syntax
#= require react_ujs
#= require_tree components

Add this to config/environments/production.rb

Rails.config.react.variant = :production

And this to config/environments/development.rb

Rails.config.react.variant = :development

Hello World

Create app/assets/javascripts/components/hello.jsx.coffee (note the file extension):

###* @jsx React.DOM ###

window.Hello = React.createClass
  render: ->


<html><div data-react-class="Hello" data-react-props=<%= { name: 'John' }.to_json %>/>
  <%= react_component 'Hello', name: 'John' %>


  • Unexpected token ‘<’ Error

Did you forget to add this to the top of your React component file (.js.jsx)?

/** @jsx React.DOM */

or this to your CoffeeScript component (.jsx.coffee):

###* @jsx React.DOM ###

  • Target container is not a DOM element.

Does the DOM element exist?

Did you forget to call React.renderComponent in jQuery’s $(document).ready?

  • Adjacent XJS elements must be wrapped in an enclosing tag

Multiple nodes need a parent element:

<ul> // Doesn't work without <ul> wrapper

  • Still doesn’t work?

react-rails is not stable; expect it to break.


React.js Google Group
React.js and jQuery sortable
React.js and select2
React.js and Bootstrap Modal
React.js and Kendo UI

  • You need to change the HTML “class” attribute to “className” in JSX

How to configure a no-www redirection on Amazon AWS (S3 and Cloudfront)

How do you configure a site hosted on Amazon AWS, e.g. a static website, to redirect from “www” to the “no-www” domain (aka “naked domain”)? The tool for the job is the AWS CLI.

For example, this creates a redirection from www.×.com to x.com for a bucket named www.×.com:

aws s3api put-bucket-website --bucket www.x.com --website-configuration '{
    "RedirectAllRequestsTo": {
        "HostName": "x.com"

Use this command to check that the configuration is set properly:

aws s3api get-bucket-website --bucket www.x.com

World's Smallest Screenshot Server?

require 'base64'
require 'selenium-webdriver'

class ScreenshotMiddleware
  def initialize(app)
    @app = app

  def screenshot(url, width, height, file)
      driver = Selenium::WebDriver.for :firefox
      driver.manage.window.resize_to(width, height)
      driver.navigate.to url

  def call(env)
    req = Rack::Request.new(env)
    width = req.params.fetch('width') { 1024 }
    height = req.params.fetch('height') { 768 }
    url = req.params.fetch('url')
    file = Base64.urlsafe_encode64(req.params.inspect) + ".png"
    screenshot(url, width, height, file)
    env['PATH_INFO'] = "/#{file}"

use ScreenshotMiddleware
run Rack::URLMap.new  "/" => Rack::Directory.new('screenshots')

Also see How to capture screenshots with Selenium, Ruby and Firefox.

Screenshot server API

How to use the AWS Command Line Interface

How to use the AWS Command Line Interface Documentation.

AWS CLI doesn’t support Cloudfront at the moment, see list of supported services for details.

Install the Amazon AWS command line client

$ pip install awscli
# or
$ sudo easy_install awscli

Now you need to configure the client:

$ aws configure

How to create an S3 bucket

aws s3 mb s3://xxx

How to list S3 buckets

$ aws s3 ls

How to configure a website

$ aws s3 website help

How to configure the index and error documents of a website

aws s3api put-bucket-website --bucket xxx.com --website-configuration '{
    "IndexDocument": {
        "Suffix": "index.html"
    "ErrorDocument": {
        "Key": "404/index.html"

How to set the website policy

aws s3api put-bucket-policy --bucket www.xxx.com --policy '{
  "Version": "2012-10-17",
  "Statement": [
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::www.xxx.com/*"

How to get the website configuration

 $ aws s3api get-bucket-website --bucket x.com

How to configure redirection for your website

This creates a redirection from x.com to www.×.com:

aws s3api put-bucket-website --bucket x.com --website-configuration '{
    "RedirectAllRequestsTo": {
        "HostName": "www.x.com"

How to set the error document

$ aws s3 website s3://xxx --index-document index.html --error-document 404/index.html

How to upload a website to S3

$ aws s3 sync ~/xxx s3://xxx --delete --cache-control \"max-age=3600\" --acl public-read --exclude *.txt

Note that the command will:

  • delete files from S3 that don’t exist locally.
  • set max-age header to 3600
  • allow anyone to access the files
  • exclude *.txt files