Rails manually redirects from bare domain

So, currently I am manually routing from a bare domain due to restrictions with my hosting provider (Heroku). Everything works perfectly. The problem is that if users visit mydomain.com/route, the redirect will be sent to www.mydomain.com without / route. How would I go to re-add the route, but still redirected to www.

class ApplicationController < ActionController::Base protect_from_forgery before_filter :ensure_domain APP_DOMAIN = 'www.domain.com' def index end def ensure_domain if Rails.env.production? if request.env['HTTP_HOST'] != APP_DOMAIN redirect_to "http://#{APP_DOMAIN}", :status => 301 end end end end 

EDIT

I removed my code from my ApplicationController and decided to use a refractive stone , as suggested by hurikhan77, which solved my problem.

Here refraction_rules.rb is used.

 Refraction.configure do |req| if req.host == "domain.com" req.permanent! :host => "www.domain.com" end end 
+4
source share
3 answers

I suggest using a refractive stone for this: http://rubygems.org/gems/refraction

+5
source

Ideally, you should configure these rules in your web server settings. Requests will be faster because they won’t even reach the rail stack. There was no need to add code to your application.

However, if you work in some limited environment, for example heroku, I would advise adding rack middleware. (Only for recommendations, cannot guarantee that this particular code is an error)

 class Redirector SUBDOMAIN = 'www' def initialize(app) @app = app end def call(env) @env = env if redirect? redirect else @app.call(env) end end private def redirect? # do some regex to figure out if you want to redirect end def redirect headers = { "location" => redirect_url } [302, headers, ["You are being redirected..."]] # 302 for temp, 301 for permanent end def redirect_url scheme = @env["rack.url_scheme"] if @env['SERVER_PORT'] == '80' port = '' else port = ":#{@env['SERVER_PORT']}" end path = @env["PATH_INFO"] query_string = "" if !@env ["QUERY_STRING"].empty? query_string = "?" + @env["QUERY_STRING"] end host = "://#{SUBDOMAIN}." + domain # this is where we add the subdomain "#{scheme}#{host}#{path}#{query_string}" end def domain # extract domain from request or get it from an environment variable etc. end end 

You can also test all this in isolation.

 describe Redirector do include Rack::Test::Methods def default_app lambda { |env| headers = {'Content-Type' => "text/html"} headers['Set-Cookie'] = "id=1; path=/\ntoken=abc; path=/; secure; HttpOnly" [200, headers, ["default body"]] } end def app() @app ||= Rack::Lint.new(Redirector.new(default_app)) end it "redirects unsupported subdomains" do get "http://example.com/zomg?a=1" last_response.status.should eq 301 last_response.header['location'].should eq "http://www.example.com/zomg?a=1" end # and so on end 

Then you can add it only to production (or to any preferred environment)

 # production.rb # ... config.middleware.insert_after 'ActionDispatch::Static', 'Redirector' 

If you want to test it in development, add the same line to development.rb and add an entry to your hosts file (usually / etc / hosts) to treat yoursubdomain.localhost as 127.0.0.1

+2
source

Not sure if this is the best solution, but you can re-select request.referrer and pull something after .com and add it to APP_DOMAIN

Or I think you could just pull it all up to the first. in request.env['HTTP_HOST'] add a replacement to http://www. provided that you do not plan to use subdomains.

0
source

Source: https://habr.com/ru/post/1448033/


All Articles