diff --git a/Gemfile b/Gemfile index a15645b..6e02e5c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" gem 'sinatra' - +gem 'dnsruby' group :test do gem 'minitest' gem 'mina' diff --git a/Gemfile.lock b/Gemfile.lock index 7bd4cfb..391ae0c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,35 +1,37 @@ GEM remote: https://rubygems.org/ specs: - daemons (1.2.3) - eventmachine (1.0.8) - mina (0.3.7) + daemons (1.2.4) + dnsruby (1.60.0) + eventmachine (1.2.1) + mina (1.0.3) open4 (~> 1.3.4) rake - minitest (5.7.0) + minitest (5.10.1) open4 (1.3.4) - rack (1.6.4) + rack (1.6.5) rack-protection (1.5.3) rack - rake (10.4.2) - sinatra (1.4.6) - rack (~> 1.4) + rake (11.3.0) + sinatra (1.4.7) + rack (~> 1.5) rack-protection (~> 1.4) tilt (>= 1.3, < 3) - thin (1.6.3) + thin (1.7.0) daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0) - rack (~> 1.0) - tilt (2.0.1) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) + tilt (2.0.5) PLATFORMS ruby DEPENDENCIES + dnsruby mina minitest sinatra thin BUNDLED WITH - 1.10.5 + 1.13.6 diff --git a/lightsaber.rb b/lightsaber.rb index c25f8de..c22cb20 100644 --- a/lightsaber.rb +++ b/lightsaber.rb @@ -1,5 +1,7 @@ +require 'rubygems' require 'uri' require 'rack/response' +require 'dnsruby' # This is the class that resolves a given URL # to what we need to redirect to @@ -17,21 +19,31 @@ class Lightsaber end end - def get_response_from_yml - res = Rack::Response.new + def get_response_from_dns (host) - YAML::load_file('redirects.yml').each do |code, zone| - if zone.has_key? @url.host.to_s - url = get_url(zone[@url.host], @url.path) - if url - res.redirect url, code - else - res.status = 400 - res.body = "Invalid configuration for #{@url.host}" + res = not_setup_response + + ret = Dnsruby::Resolver.new.query("_redirect.#{host}", 'TXT') + ret.answer.rrsets.each do |rrset| + rrset.rrs.each do |rr| + if is_valid_lightsaber_record? rr.data + url = get_redirect_from_dns_record rr.data + if url =~ /\A#{URI::regexp}\z/ + res = Rack::Response.new + res.redirect url + end end - return res end end + res + end + + def get_redirect_from_dns_record(data) + data[6..-1] + end + + def is_valid_lightsaber_record? (data) + data[0..5] === 'v=lr1;' end def not_setup_response @@ -42,10 +54,6 @@ class Lightsaber def get_response - - yml_res = get_response_from_yml - return yml_res unless yml_res.nil? - - not_setup_response + get_response_from_dns @url.host end end \ No newline at end of file diff --git a/redirects.yml b/redirects.yml index 6cf7516..0d9ca91 100644 --- a/redirects.yml +++ b/redirects.yml @@ -14,4 +14,4 @@ 302: fb.captnemo.in: https://facebook.com/captn3m0 where.rzp.io: https://goo.gl/maps/1A9nhMPzehS2 - where.razorpay.com: https://goo.gl/maps/1A9nhMPzehS2 + where.razorpay.com: https://goo.gl/maps/1A9nhMPzehS2 \ No newline at end of file diff --git a/test.rb b/test.rb index 031b228..13a533e 100644 --- a/test.rb +++ b/test.rb @@ -2,6 +2,7 @@ require 'minitest/autorun' require 'resolv' require 'yaml' require 'pp' +require_relative './lightsaber' class TestConfig < Minitest::Test REDIRECTS = [301, 302] @@ -15,6 +16,11 @@ class TestConfig < Minitest::Test end end + def test_txt_record + saber = Lightsaber.new 'http://localhost:9292/test' + pp saber.get_response_from_dns 'captnemo.in' + end + def test_each_domain @config.each do |section, zone| zone.each do |domain, redirect|