Develop Rack Middleware for Redirect to Each Path

- 3 mins

I’ve developed a Rack middleware; called RackJoint. The middleware helps you to redirect as Rack application with Chef like DSL.

What is the RackJoint

RackJoint allows you to redirect with changing Rack responses. Its configuration requires Chef like Ruby DSL.

I believe that major feature is that this middleware users can set each path’s redirections. There are middlewares that redirect for domains. For example, It redirects to ‘example.com’ from ‘example.org’, In this middleware, you cannot set following case:

I’ve assumed that RackJoint is used for Rack application because, in case of Rails app, routes.rb can have responsibility to the middleware’s behaviors. However, when you would like to redirect to many paths, the middleware is perhaps useful.

How to use it?

# config.ru

require 'rack/joint'

use Rack::Joint do
  host 'example.com' do
    # If you access `http://example.com/dogs/bark.html`,
    # redirect to `http://example.org/bowwow.html` with 301.
    redirect '/dogs/bark.html' do
      new_host 'example.org'
      to '/bowwow.html'
      status 301
    end

    # If you access `http://example.com/cats.html`,
    # redirect to `https://example.org/meow/mew` with 302.
    redirect '/cats.html' do
      new_host 'example.org'
      ssl true
      to '/meow/mew'
      status 302
    end
  end

  host 'example.net' do
    # If you access `http://example.net/frog.html`,
    # redirect to `http://example.net/croak` with 301.
    redirect '/frog.html' do
      to '/croak'
    end

    # If you access `http://example.net/quack`,
    # redirect to `http://example.org/quack` with 301.
    redirect '/quack' do
      new_host 'example.org'
    end
  end
end

run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['Hello World!']] }

host resource

host is a base resource. It is required to use this middleware. It responds to request hostname.

redirect resource

redirect declares requested path name. It is required to set to set redirecting.

ssl resource

ssl is the option to control whether to enable ssl or not. Without the option, the scheme of response for redirect will be the same one of request. For example:

# config.ru

host 'example.com' do
  redirect '/old-path' do
    new_host 'example.org'
  end
end

There is configuration above, when request with ‘http://example.com’, respond to ‘http://example.org’; and when ‘https://example.com’, request with ‘https’.

new_host resource

new_host is the hostname for response to redirect. Without the option, requested host will be used for Location to response.

# config.ru

host 'example.com'
  redirect '/old-path' do
    new_host 'example.org'
    to '/new-path'
  end

  redirect '/too/old-path' do
    to '/same-hosts-path'
  end
end

In this config above, when request ‘http://example.com/old-path’, it will redirect to ‘http://example.org/new-path’, however; when ‘http://example.org/too/old-path’, it’ll redirect to ‘http://example.com/same-hosts-path’. This is because the second directive doesn’t have new_host.

to resource

to is the path name for response to redirect. In principles, the option is required, but if new_host is set, to option isn’t an essential option.

# config.ru

host 'example.com' do
  redirect '/same-path' do
    new_host 'example.org'
  end

  # It will raise exception because there are `host` nor `to` option.
  redirect '/old-path' do
    status 301
  end
end

In the case, when request ‘http://example.com/same-path’, the response will be ‘http://example.org/same-path’.

status resource

status controls status code for redirect. Its default value is 301, and the middleware supports 301, 302, 303, 307, 308.

Why did I develop RackJoint?

I looked for similar middleware before created RackJoint, but I noticed that there are few middlewares to keeping maintenance. And I’d like to write Chef like DSL.

I haven’t dealt with port number and other headers parameters yet so that I’d like to modify usability. I took much time to develop RackJoint because I was lack of comprehension for Rack. As I was interested in middleware developing, I’ll continue to develop applications.

Akito Kasai

Akito Kasai

Support Engineer and Software developer in Japan.

rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora