Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/http/handler/erb.rb
Views: 11766
# -*- coding: binary -*-1require 'erb'2include ERB::Util34module Rex5module Proto6module Http78###9#10# This class implements a handler for ERB (.rhtml) template files. This is11# based off the webrick handler.12#13###14class Handler::Erb < Handler1516#17# ERB handlers required a relative resource so that the full path name can18# be computed.19#20def self.relative_resource_required?21true22end2324#25# Initializes the ERB handler26#27def initialize(server, root_path, opts = {})28super(server)2930self.root_path = root_path31self.opts = opts3233self.opts['MimeType'] = "text/html" unless self.opts['MimeType']34end3536#37# Called when a request arrives.38#39def on_request(cli, req)40resource = req.relative_resource4142# Make sure directory traversals aren't happening43if (resource =~ /\.\./)44wlog("Erb::on_request: Dangerous request performed: #{resource}",45LogSource)46return47# If the request is for the root directory, use the document index file.48elsif (resource == '/')49resource << opts['DocumentIndex'] || 'index.rhtml'50end5152begin53resp = Response.new5455# Calculate the actual file path on disk.56file_path = root_path + resource5758# Serialize the contents of the file59data = ''6061File.open(file_path, 'rb') { |f|62data = f.read63}6465# Set the content-type to text/html by default. We do this before66# evaluation so that the script can change it.67resp['Content-Type'] = server ? server.mime_type(resource) : 'text/html'6869# If the requested file is a ruby html file, evaluate it.70if (File.extname(file_path) == ".rhtml")71# Evaluate the data and set the output as the response body.72resp.body = evaluate(ERB.new(data), cli, req, resp)73# Otherwise, just set the body to the data that was read.74else75resp.body = data76end77rescue Errno::ENOENT78server.send_e404(cli, req)79rescue => e80elog('Erb::on_request', LogSource, error: e)8182resp.code = 50083resp.message = "Internal Server Error"84resp.body =85"<html><head>" +86"<title>Internal Server Error</title>" +87"</head><body> " +88"<h1>Internal Server Error</h1>" +89"The server encountered an error:<br/><br/> <b>" + html_escape($!) + "</b><br/><br/>" +90"Stack trace:<br/><br/>" +91$@.map { |e| html_escape(e.to_s) }.join("<br/>") +92"</body></html>"93end9495# Send the response to the96if (cli and resp)97cli.send_response(resp)98end99100resp101end102103#104# Evaluates the ERB context in a specific binding context.105#106def evaluate(erb, cli, request, response)107# If the thing that created this handler wanted us to use a callback108# instead of the default behavior, then let's do that.109if (opts['ErbCallback'])110opts['ErbCallback'].call(erb, cli, request, response)111else112Module.new.module_eval {113query_string = request.qstring114meta_vars = request.meta_vars115erb.result(binding)116}117end118end119120protected121122attr_accessor :root_path, :opts # :nodoc:123124end125126end127end128end129130131