diff --git a/lib/travis/web/app.rb b/lib/travis/web/app.rb
index f6420ac0..31466a28 100644
--- a/lib/travis/web/app.rb
+++ b/lib/travis/web/app.rb
@@ -11,12 +11,18 @@ class Travis::Web::App
# Simple Rack router that behaves like a hash.
# Key is the path, value the response.
class Router < DelegateClass(Hash)
- def initialize
+ attr_reader :main_app
+ def initialize(main_app)
+ @main_app = main_app
super({})
end
def call(env)
- self[env['PATH_INFO']]
+ if main_app.custom_branch?(env)
+ main_app.response_for_custom_branch(env)
+ else
+ self[env['PATH_INFO']]
+ end
end
end
@@ -31,7 +37,7 @@ class Travis::Web::App
@options = options
@environment = options.fetch(:environment)
@root = options.fetch(:root)
- @router = Router.new
+ @router = Router.new(self)
@app = builder.to_app
@version = File.read File.expand_path('version', root)
@last_modified = Time.now
@@ -43,16 +49,53 @@ class Travis::Web::App
app.call(env)
end
+ def response_for_custom_branch(env)
+ status, headers, body = response_for File.join(root, 'index.html'), custom_branch: custom_branch(env)
+ response = Rack::Response.new body, status, headers
+
+ if disable_custom_branch?(env)
+ response.delete_cookie 'custom_branch'
+ elsif custom_branch_from_params(env)
+ response.set_cookie 'custom_branch', value: custom_branch_from_params(env), expires: Time.now + 31536000
+ end
+
+ response.finish
+ end
+
+ def custom_branch?(env)
+ custom_branch(env) || disable_custom_branch?(env)
+ end
+
private
+ def disable_custom_branch?(env)
+ env['QUERY_STRING'] =~ /disable[_-]custom[_-]branch/
+ end
+
+ def custom_branch_from_params(env)
+ branch = custom_branch_from_string env['QUERY_STRING']
+ end
+
+ def custom_branch_from_cookie(env)
+ custom_branch_from_string env['HTTP_COOKIE']
+ end
+
+ def custom_branch_from_string(string)
+ $1 if string =~ /(? content.bytesize.to_s,
@@ -113,13 +156,18 @@ class Travis::Web::App
Rack::Mime.mime_type File.extname(file)
end
- def set_config(string)
+ def set_config(string, options = {})
string.gsub! %r(]*>) do
%()
end
- string.gsub! %r{(src|href)="(\/?)((styles|scripts)\/[^"]*)"} do
- %(#$1="#$2#{version}/#$3")
+ string.gsub! %r{(src|href)="(?:\/?)((styles|scripts)\/[^"]*)"} do
+ if options[:custom_branch]
+ url = "https://s3.amazonaws.com/travis-web-production/assets/#{options[:custom_branch]}/#{$2}"
+ %(#$1="#{url}")
+ else
+ %(#$1="/#{version}/#$2")
+ end
end
end
diff --git a/spec/app_spec.rb b/spec/app_spec.rb
index 3b4f4698..584616ba 100644
--- a/spec/app_spec.rb
+++ b/spec/app_spec.rb
@@ -30,4 +30,24 @@ describe Travis::Web::App do
example { headers['Cache-Control'].should be == 'no-cache' }
example { headers['Vary'].split(',').should_not include('Accept') }
end
+
+ describe 'custom branch' do
+ context 'when passing custom branch as a param' do
+ before { get('/?custom-branch=foo') }
+ example { last_response.should be_ok }
+ example { last_response.body.should include('/assets/foo/styles/app.css') }
+ example { last_response.body.should include('/assets/foo/scripts/app.js') }
+ example { headers['Set-Cookie'].should include('custom_branch=foo') }
+ end
+
+ context 'disabling custom branch' do
+ before { get('/?disable-custom-branch=true') }
+ example { last_response.should be_ok }
+ example { last_response.body.should =~ %r{src="/[^\/]+/scripts/app.js} }
+ example { last_response.body.should_not include('/assets/true/styles/app.css') }
+ example { last_response.body.should_not include('/assets/foo/styles/app.css') }
+ example { last_response.body.should_not include('/assets/foo/scripts/app.js') }
+ example { headers['Set-Cookie'].should include('custom_branch=;') }
+ end
+ end
end