TL; DR; - Динамический рубиновый контент (т. Е. .rhtml
файлы) должен отображаться механизмом шаблонов;Встроенный движок, используемый WebRick - это движок Ruby ERB
;Рендеринг динамических файлов перед отправкой ответа Rack.
Я бы порекомендовал отделить статические файлы от динамических файлов.
Это позволит оптимизироватьстатическая файловая служба, использующая либо обратный прокси-сервер (т. е. nginx), либо статический файловый сервер Ruby (т. е. йод).
Общий подход заключается в следующем:
Ваше приложение Rackнужно будет обрабатывать динамические файлы, используя соответствующий процессор шаблонизатора.
Для ваших .rhtml
файлов я бы предположил , что это будет встроенный шаблонизатор ERB
(естьхороший пост об этом здесь ).
Предполагая, что вы разместили свои динамические и статические файлы, как уже упоминалось, вы можете начать с файла config.ru
, который выглядиткак это:
require 'erb'
require 'pathname'
ROOT ||= Pathname.new(File.dirname(__FILE__)).expand_path
module APP
VIEWS = ROOT.join('app', 'views')
def self.call(env)
# prevent folder trasversal (security) and extract file name
return [403, {}, ["Not Allowed!"]] if env['PATH_INFO'].index("..") || env['PATH_INFO'].index("//")
filename = VIEWS.join(env['PATH_INFO'][1..-1])
# make sure file exists
return [404, {}, ["Not Found"]] unless File.exists?(filename)
# process dynamic content
template = IO.binread filename
data = ERB.new(template).result(binding)
return [200, {}, [data]]
end
end
run APP
Далее вы можете запустить приложениеih iodine, который будет обрабатывать статическую файловую сервисную часть (в данном примере - однопоточный рабочий на ядро):
iodine -w -1 -t 1 -www public
Конечно, вы можете использовать промежуточное ПО Rack::Static
, но оно должно бытьбыть значительно медленнее (отметьте это сами или протестируйте на предмет Thin) ...
... Я автор йода, так что я могу быть предвзятым.
EDIT
PS (примечание о безопасности и производительности)
Я бы пересмотрел механизм шаблонов.
ERB быстр и эффективен, однако он также позволяет выполнять код внутри шаблона.
Это может привести к сложному обслуживанию проекта, так как код просачивается в шаблон, делая код менее читаемым и сложным в обслуживании.
Я бы рассмотрел переход на шаблоны Mustache, которые препятствуют выполнению кода внутри шаблона..
Изменение механизма шаблонов также может повысить производительность.Рассмотрим следующий тест с использованием шаблонов усов со вкусом йода (которые предлагают агрессивный выход из HTML):
require 'iodine'
require 'erb'
require 'benchmark'
module Base
ERB_ENG = ERB.new("<%= data %> <%= Time.now %>")
MUS_ENG = Iodine::Mustache.new(nil, "{{ data }} {{ date }}")
def self.render_erb(data)
ERB_ENG.result(binding)
end
def self.render_mus(data)
h = {data: data, date: Time.now.to_s }
MUS_ENG.render(h)
end
end
puts "#{Base.render_mus("hello")} == #{Base.render_erb("hello")} : #{(Base.render_mus("hello") == Base.render_erb("hello"))}"
TIMES = 100_000
Benchmark.bm do |bm|
bm.report("Ruby ERB") { TIMES.times { Base.render_erb("hello") } }
bm.report("Iodine ") { TIMES.times { Base.render_mus("hello") } }
end
Результаты на моем компьютере были (чем ниже, тем лучше):
user system total real
Ruby ERB 1.701363 0.006301 1.707664 ( 1.709132)
Iodine 0.256918 0.000750 0.257668 ( 0.258190)
Опять же, поскольку я автор йода, я предвзят.Поиграйте и найдите то, что лучше для вас.