Giter Site home page Giter Site logo

rack-host-redirect's Introduction

Rack::HostRedirect

A lean and simple Rack middleware that 301 redirects requests from one host to another.

This is useful for environments where it's difficult or impossible to implement this via Nginx/Apache configuration (e.g. Heroku.)

I'm using this to redirect traffic from a *.herokuapp.com subdomain to a custom domain, and to redirect the www subdomain to the bare domain.

Configuration below is for Rails, but this middleware should also work just fine with Sinatra and bare Rack apps.

Rails configuration

in Gemfile:

gem 'rack-host-redirect'

in config/environments/production.rb:

config.middleware.use Rack::HostRedirect, {
  'myapp.herokuapp.com' => 'www.myapp.com'
}

With this configuration, all requests to myapp.herokuapp.com will be 301 redirected to www.myapp.com.

Path, querystring and protocol are preserved, so a request to:

https://myapp.herokuapp.com/foo?bar=baz

will be 301 redirected to:

https://www.myapp.com/foo?bar=baz

Addtional host redirections can be specified as key-value pairs in the host mapping hash:

config.middleware.use Rack::HostRedirect, {
  'myapp.herokuapp.com' => 'www.myapp.com',
  'old.myapp.com'       => 'new.myapp.com'
}

Multiple hosts that map to the same redirect destination host can be specified by an Array key:

config.middleware.use Rack::HostRedirect, {
  %w(myapp.herokuapp.com foo.myapp.com) => 'www.myapp.com'
}

URI methods to set for redirect location can be specified as a hash value:

# Don't preserve path or query on redirect:
config.middleware.use Rack::HostRedirect, {
  'bar.myapp.com' => {host: 'www.myapp.com', path: '/', query: nil}
}

When specifying a URI methods hash, the :host key is required; all other URI keys are optional.

Skip redirect for special cases (e.g. Let's Encrypt)

When you specify a host redirect, it will redirect all requests to that host, but if you need certain exclusions to this -- e.g. you're handling a Let's Encrypt challenge request in your app, so you need to let that pass through -- you can do so via passing in a Proc to the :exclude key:

# Allow ACME challenge request to pass through, redirect everything else:
config.middleware.use Rack::HostRedirect, {
  'www.example.com' => {
    host: 'example.com', 
    exclude: -> (request) { request.path.start_with?('/.well-known/acme-challenge/') }
  }
}

The proc will be called for each request with the Rack::Request object. If the proc returns a truthy value, the request will pass through without a redirect.

With ActionDispatch::SSL

If your app is setting config.force_ssl = true and you're redirecting from a domain for which you don't maintain certs, you should insert Rack::HostRedirect ahead of ActionDispatch::SSL in the middleware stack, so that the redirect happens before the SSL upgrade:

config.middleware.insert_before ActionDispatch::SSL, Rack::HostRedirect, {
  'www.legacy-domain.com' => 'www.myapp.com'
}

rack-host-redirect's People

Contributors

gbuesing avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rack-host-redirect's Issues

Domain redirection with params.

Hi
Im using this example

config.middleware.use Rack::HostRedirect, { 'bar.myapp.com' => {host: 'www.myapp.com', path: '/', query: nil} }

to redirect domain.foo => domain.bar/foo.
All working fine except that I cannot pass links here. as example

domain.foo/test => domain.bar/foo (/test missing)

Can I do something like this

domain.foo/test => domain.bar/foo/test ?

Feature request: skip redirection on certain routes

Thanks for creating this gem - it's very useful!

I'm wondering if it's possible to add a feature to skip redirection on certain routes.

Here's the use case: I'm using Let's Encrypt (https://letsencrypt.org) for automated SSL encryption. The LE http-01 method of requires verification of a challenge/response on each requested domain before issuing certificates. I'm trying to automatically issue certificates on example.com and www.example.com.

I'm currently using rack-host-redirect to strip www from all requests:

use Rack::HostRedirect, {
    'www.example.com' => 'example.com'
}

When LE verification attempts to verify the response at www.example.com/.well-known/acme-challenge/* (where * is the challenge string), verification fails because of the 301 redirect, even though the server provides the correct response after the redirect.

Is there a straightforward way to add a feature that will allow skipping redirection on requests on a route like www.example.com/.well-known/acme-challenge/* so verification can pass?

Thanks for considering, and happy to help however I can. (I'm reading the code now, but I'm not familiar enough with Rack to contribute a pull request yet...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.