examples/wikipedia-dns.rb in rubydns-2.0.1 vs examples/wikipedia-dns.rb in rubydns-2.0.2

- old
+ new

@@ -21,80 +21,93 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'rubydns' -require 'process/daemon' -require 'process/daemon/privileges' - require 'cgi' -require 'nokogiri' require 'json' require 'digest/md5' -require 'http' +require 'async/logger' +require 'async/http/client' +require 'async/dns/extensions/string' +require 'async/http/url_endpoint' -# You might need to change the user name "daemon". This can be a user name -# or a user id. -RUN_AS = 'daemon' - -if Process::Daemon::Privileges.current_user != 'root' - $stderr.puts 'Sorry, this command needs to be run as root!' - exit 1 -end - # Encapsulates the logic for fetching information from Wikipedia. module Wikipedia + ENDPOINT = Async::HTTP::URLEndpoint.parse("https://en.wikipedia.org") + + def self.lookup(title, logger: nil) + client = Async::HTTP::Client.new([ENDPOINT]) + url = self.summary_url(title) + + logger&.info "Making request to #{ENDPOINT} for #{url}." + response = client.get(url, {'Host' => ENDPOINT.hostname}) + logger&.info "Got response #{response.inspect}." + + if response.status == 301 + return lookup(response.headers['HTTP_LOCATION']) + else + return self.extract_summary(response.body).force_encoding('ASCII-8BIT') + end + end + def self.summary_url(title) - "http://en.wikipedia.org/w/api.php?action=parse&page=#{CGI.escape title}&prop=text&section=0&format=json" + "/api/rest_v1/page/summary/#{CGI.escape title}" end def self.extract_summary(json_text) document = JSON.parse(json_text) - return Nokogiri::HTML(document['parse']['text']['*']).css('p')[0].text + + return document['extract'] rescue return 'Invalid Article.' end end # A DNS server that queries Wikipedia and returns summaries for # specifically crafted queries. -class WikipediaDNS < Process::Daemon +class WikipediaDNS Name = Resolv::DNS::Name IN = Resolv::DNS::Resource::IN + + INTERFACES = [ + [:udp, '::', 5300], + [:tcp, '::', 5300], + ] def startup # Don't buffer output (for debug purposes) $stderr.sync = true stats = { requested: 0 } # Start the RubyDNS server - RubyDNS.run_server do + RubyDNS.run_server(INTERFACES) do on(:start) do - Process::Daemon::Privileges.change_user(RUN_AS) + # Process::Daemon::Privileges.change_user(RUN_AS) + if ARGV.include?('--debug') @logger.level = Logger::DEBUG else @logger.level = Logger::WARN end + + @logger.info "Starting Wikipedia DNS..." end match(/stats\.wikipedia/, IN::TXT) do |transaction| transaction.respond!(*stats.inspect.chunked) end match(/(.+)\.wikipedia/, IN::TXT) do |transaction, match_data| title = match_data[1] stats[:requested] += 1 - - url = Wikipedia.summary_url(title) - response = HTTP.get(url) # socket_class: ... is not yet supported. - - summary = - Wikipedia.extract_summary(response).force_encoding('ASCII-8BIT') + + summary = Wikipedia.lookup(title, logger: @logger) + transaction.respond!(*summary.chunked) end # Default DNS handler otherwise do |transaction| @@ -102,6 +115,7 @@ end end end end -WikipediaDNS.daemonize +wikipedia_dns = WikipediaDNS.new +wikipedia_dns.startup