From 371ea7d4d58ab25f7c45ebdbe56cd60cce1d240a Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Sun, 23 Feb 2014 16:37:28 -0700 Subject: [PATCH 1/8] Adds capability for specifying exclusive hosts to perform redirect on --- lib/rack/no-www.rb | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/rack/no-www.rb b/lib/rack/no-www.rb index e1dc081..79d414b 100644 --- a/lib/rack/no-www.rb +++ b/lib/rack/no-www.rb @@ -5,19 +5,33 @@ class NoWWW STARTS_WITH_WWW = /^www\./i - def initialize(app) + def initialize(app, options={}) + default_options = { + only_hosts: [] + } + @app = app + @options = default_options.merge(options) end def call(env) - if env['HTTP_HOST'] =~ STARTS_WITH_WWW + if require_direct? [301, no_www_request(env), ["Moved Permanently\n"]] else @app.call(env) end end - private + private + + def require_redirect? + env['HTTP_HOST'] =~ STARTS_WITH_WWW && host_match? + end + + def host_match? + @options[:only_hosts].include?(env['HTTP_HOST']) unless @options[:only_hosts].empty? + end + def no_www_request(env) { 'Location' => Rack::Request.new(env).url.sub(/www\./i, ''), 'Content-Type' => 'text/html' } From eeb96a91f8b99eb30666f338ab34307536a3cac0 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Tue, 25 Feb 2014 20:25:49 -0700 Subject: [PATCH 2/8] Fixes name error --- lib/rack/no-www.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rack/no-www.rb b/lib/rack/no-www.rb index 79d414b..c73dc23 100644 --- a/lib/rack/no-www.rb +++ b/lib/rack/no-www.rb @@ -15,7 +15,7 @@ def initialize(app, options={}) end def call(env) - if require_direct? + if require_redirect? [301, no_www_request(env), ["Moved Permanently\n"]] else @app.call(env) From c1b0c778233b6c8a0c7b5733363c047aeba63359 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Tue, 25 Feb 2014 20:40:00 -0700 Subject: [PATCH 3/8] Fixes name error --- lib/rack/no-www.rb | 5 +++-- lib/rack/no-www/version.rb | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/rack/no-www.rb b/lib/rack/no-www.rb index c73dc23..e7be3b7 100644 --- a/lib/rack/no-www.rb +++ b/lib/rack/no-www.rb @@ -15,6 +15,7 @@ def initialize(app, options={}) end def call(env) + @env = env if require_redirect? [301, no_www_request(env), ["Moved Permanently\n"]] else @@ -25,11 +26,11 @@ def call(env) private def require_redirect? - env['HTTP_HOST'] =~ STARTS_WITH_WWW && host_match? + @env['HTTP_HOST'] =~ STARTS_WITH_WWW && host_match? end def host_match? - @options[:only_hosts].include?(env['HTTP_HOST']) unless @options[:only_hosts].empty? + @options[:only_hosts].include?(@env['HTTP_HOST']) unless @options[:only_hosts].empty? end def no_www_request(env) diff --git a/lib/rack/no-www/version.rb b/lib/rack/no-www/version.rb index 3df9651..a087ae2 100644 --- a/lib/rack/no-www/version.rb +++ b/lib/rack/no-www/version.rb @@ -1,5 +1,5 @@ module Rack class NoWWW - VERSION = "0.0.2" + VERSION = "0.0.4" end end From 141e8cfce8ef7208ae2625bf71aba681376e09e7 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Thu, 27 Feb 2014 21:31:29 -0700 Subject: [PATCH 4/8] Fixes logic error in detecting only hosts --- lib/rack/no-www.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/rack/no-www.rb b/lib/rack/no-www.rb index e7be3b7..416d6c4 100644 --- a/lib/rack/no-www.rb +++ b/lib/rack/no-www.rb @@ -17,9 +17,9 @@ def initialize(app, options={}) def call(env) @env = env if require_redirect? - [301, no_www_request(env), ["Moved Permanently\n"]] + [301, no_www_request, ["Moved Permanently\n"]] else - @app.call(env) + @app.call(@env) end end @@ -30,11 +30,11 @@ def require_redirect? end def host_match? - @options[:only_hosts].include?(@env['HTTP_HOST']) unless @options[:only_hosts].empty? + @options[:only_hosts].include?(@env['HTTP_HOST']) || @options[:only_hosts].empty? end - def no_www_request(env) - { 'Location' => Rack::Request.new(env).url.sub(/www\./i, ''), + def no_www_request + { 'Location' => Rack::Request.new(@env).url.sub(/www\./i, ''), 'Content-Type' => 'text/html' } end From 80401a240d7c6fbba82be0ba5af736ec8b1b8ba2 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Thu, 27 Feb 2014 21:43:38 -0700 Subject: [PATCH 5/8] Fixes logic error in detecting only hosts --- spec/rack_no_www_spec.rb | 53 +++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/spec/rack_no_www_spec.rb b/spec/rack_no_www_spec.rb index 56109af..6ca95f1 100644 --- a/spec/rack_no_www_spec.rb +++ b/spec/rack_no_www_spec.rb @@ -9,28 +9,53 @@ def app app = Rack::NoWWW.new(mock_endpoint) end + + describe "when receiving a request with a 'www'" do + context "without the only_hosts parameter" do + let(:app) { ->(env) { [200, env, "app"] } } + + let :middleware do + Rack::NoWWW.new(app) + end - before(:each) do - request '/', {'HTTP_HOST' => 'www.example.org' } - end + before(:each) do + request '/', {'HTTP_HOST' => 'www.example.org' } + end - it "should issue a 301 redirect" do - last_response.status.should == 301 - end + it "should issue a 301 redirect" do + last_response.status.should == 301 + end - it "should redirect to the URL without the 'www'" do - last_response.headers['Location'].should == "http://example.org/" - end + it "should redirect to the URL without the 'www'" do + last_response.headers['Location'].should == "http://example.org/" + end + + it "should have a text/html content type" do + last_response.headers['Content-Type'].should == "text/html" + end - it "should have a text/html content type" do - last_response.headers['Content-Type'].should == "text/html" + it "should have a body of 'Moved Permanently\\n'" do + last_response.body.should == "Moved Permanently\n" + end + end - it "should have a body of 'Moved Permanently\\n'" do - last_response.body.should == "Moved Permanently\n" + context "with the only_hosts parameter not matching the domain" do + let(:app) { ->(env) { [200, env, "app"] } } + + let :middleware do + Rack::NoWWW.new(app, only_hosts: ['www.example.org']) + end + + before(:each) do + request '/', {'HTTP_HOST' => 'www.non-redirecting-host.org' } + end + + it "should not issue a 301 redirect when proper only_hosts param specified" do + last_response.status.should == 200 + end end - end describe "when receiving a request without a 'www'" do From fe3f79150b376e8935cd41a2cb93bf00e03d3e19 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Thu, 27 Feb 2014 22:11:43 -0700 Subject: [PATCH 6/8] Adds tests for new paramater option --- spec/rack_no_www_spec.rb | 49 +++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/spec/rack_no_www_spec.rb b/spec/rack_no_www_spec.rb index 6ca95f1..2672928 100644 --- a/spec/rack_no_www_spec.rb +++ b/spec/rack_no_www_spec.rb @@ -3,20 +3,13 @@ describe "Rack::NoWWW" do include Rack::Test::Methods - - def app - mock_endpoint = lambda { |env| [200, {}, ['Hello, world.']] } - app = Rack::NoWWW.new(mock_endpoint) - end - - + let(:mock_endpoint) { lambda { |env| [200, {}, ["Hello, world."]] } } describe "when receiving a request with a 'www'" do - context "without the only_hosts parameter" do - let(:app) { ->(env) { [200, env, "app"] } } + context "without the :only_hosts parameter specified" do - let :middleware do - Rack::NoWWW.new(app) + let :app do + Rack::NoWWW.new(mock_endpoint) end before(:each) do @@ -41,24 +34,44 @@ def app end - context "with the only_hosts parameter not matching the domain" do - let(:app) { ->(env) { [200, env, "app"] } } - - let :middleware do - Rack::NoWWW.new(app, only_hosts: ['www.example.org']) + context "with a non-matching domain in the :only_hosts parameter" do + let :app do + Rack::NoWWW.new(mock_endpoint, only_hosts: ['www.do-not-redirect.org']) end before(:each) do - request '/', {'HTTP_HOST' => 'www.non-redirecting-host.org' } + request '/', {'HTTP_HOST' => 'www.example.org' } end - it "should not issue a 301 redirect when proper only_hosts param specified" do + it "should not issue a 301 redirect" do last_response.status.should == 200 end end + + context "with a matching domain in the :only_hosts parameter" do + let :app do + Rack::NoWWW.new(mock_endpoint, only_hosts: ['www.example.org']) + end + + before(:each) do + request '/', {'HTTP_HOST' => 'www.example.org' } + end + + it "should issue a 301 redirect" do + last_response.status.should == 301 + end + + it "should redirect to the URL without the 'www'" do + last_response.headers['Location'].should == "http://example.org/" + end + end end describe "when receiving a request without a 'www'" do + let :app do + Rack::NoWWW.new(mock_endpoint) + end + it "should fall through to the app" do get '/' last_response.status.should == 200 From 6963bc5c33a048ba7786de19d8b698415802fbb2 Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Thu, 27 Feb 2014 22:13:57 -0700 Subject: [PATCH 7/8] Changelog --- CHANGELOG.md | 7 ++++++- lib/rack/no-www/version.rb | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 969bb56..25964b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.0.3 (February 27, 2014) + +- Added option to specify on which hosts to perform redirection + + ## 0.0.2 (June 14, 2011) - Populate CHANGELOG. @@ -9,4 +14,4 @@ ## 0.0.1 (June 22, 2010) -- Initial release +- Initial release \ No newline at end of file diff --git a/lib/rack/no-www/version.rb b/lib/rack/no-www/version.rb index a087ae2..e10147d 100644 --- a/lib/rack/no-www/version.rb +++ b/lib/rack/no-www/version.rb @@ -1,5 +1,5 @@ module Rack class NoWWW - VERSION = "0.0.4" + VERSION = "0.0.3" end end From 2094a7a7bc9c8f2ab4799e0204b445cabab1594e Mon Sep 17 00:00:00 2001 From: Sean Coleman Date: Thu, 27 Feb 2014 22:16:23 -0700 Subject: [PATCH 8/8] Readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a0d295b..a4a483c 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,12 @@ middleware at the top of the Rack stack:: end end +You can also specify the `:only_hosts` parameter to limit redirection to specific hosts + + config.middleware.use(Rack::NoWWW, only_hosts: "www.example.org") + +Requests not made on www.example.org will not be redirected to the root domain. + Credits -------