class Hostrich

Constants

VERSION

Public Class Methods

hosts() click to toggle source
# File lib/hostrich.rb, line 8
def self.hosts
  @@hosts
end
hosts=(array) click to toggle source
# File lib/hostrich.rb, line 12
def self.hosts=(array)
  @@hosts = array
end
new(app, hosts = []) click to toggle source
# File lib/hostrich.rb, line 16
def initialize(app, hosts = [])
  @app = app
  @@hosts += Array(hosts)
end

Public Instance Methods

call(env) click to toggle source
# File lib/hostrich.rb, line 21
def call(env)
  return @app.call(env) if @@hosts.empty?

  # Extract suffix from current request host.
  match = nil
  @@hosts.detect { |host|
    if http_host = env['HTTP_HOST']
      match = http_host.match(/#{host}(\.[\.\w-]+)?/)
    end
  }
  return @app.call(env) if match.nil?

  suffix = match[1]

  # Fake host in request headers.
  # Eg. If request is made from http://example.com.dev or http://example.com.127.0.0.1.xip.io,
  # the Rack app will see it just as a request to http://example.com.
  env['SERVER_NAME'] = remove_suffix(env['SERVER_NAME'], suffix)
  env.each do |key, value|
    if key.start_with?('HTTP_') && String === value
      env[key] = remove_suffix(value, suffix)
    end
  end

  # Get regular response from Rack app
  status, headers, body = @app.call(env)
  body.close if body.respond_to? :close

  chunks = []
  body.each { |chunk| chunks << chunk.to_s }
  body = chunks.join

  # Add current host suffix in all response bodies, so that occurences of http://example.com
  # appear as http://example.com.dev or http://example.com.127.0.0.1.xip.io in the browser.
  body = [add_suffix(body, suffix)]

  # Do the same in response headers. This is important for cookies and redirects.
  headers = Hash[headers.map { |k,v| [k, add_suffix(v, suffix)] }]

  # Return hacked response
  [status, headers, body]
end

Private Instance Methods

add_suffix(input, suffix) click to toggle source
# File lib/hostrich.rb, line 72
def add_suffix(input, suffix)
  output = input.dup
  # Don’t add suffix when it’s already there. Prevents double-suffix redirects and stuff.
  @@hosts.each { |host| output.gsub! /\b#{host}\b(?!#{suffix})/, "#{host}#{suffix}" }
  output
end
remove_suffix(input, suffix) click to toggle source
# File lib/hostrich.rb, line 66
def remove_suffix(input, suffix)
  output = input.dup
  @@hosts.each { |host| output.gsub! "#{host}#{suffix}", host }
  output
end