Ben*_*min 5 ruby regex mongrel http handler
我目前正在使用Mongrel开发自定义Web应用程序项目.
我希望Mongrel使用基于正则表达式的定义的Http Handler.例如,每当有人调用http://test/bla1.js或http://test/bla2.js这样的URL时,就会调用相同的Http处理程序来管理请求.
到目前为止我的代码看起来像这样:
http_server = Mongrel::Configurator.new :host => config.get("http_host") do
listener :port => config.get("http_port") do
uri Regexp.escape("/[a-z0-9]+.js"), :handler => BLAH::CustomHandler.new
uri '/ui/public', :handler => Mongrel::DirHandler.new("#{$d}/public/")
uri '/favicon', :handler => Mongrel::Error404Handler.new('')
trap("INT") { stop }
run
end
end
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我试图在这里使用正则表达式而不是字符串:
uri Regexp.escape("/[a-z0-9]+.js"), :handler => BLAH::CustomHandler.new
Run Code Online (Sandbox Code Playgroud)
但这不起作用.有解决方案吗
感谢那.
您必须将新代码注入 Mongrel 的一部分URIClassifier,否则 Mongrel 完全不知道正则表达式 URI。
以下是实现此目的的一种方法:
#
# Must do the following BEFORE Mongrel::Configurator.new
# Augment some of the key methods in Mongrel::URIClassifier
# See lib/ruby/gems/XXX/gems/mongrel-1.1.5/lib/mongrel/uri_classifier.rb
#
Mongrel::URIClassifier.class_eval <<-EOS, __FILE__, __LINE__
# Save original methods
alias_method :register_without_regexp, :register
alias_method :unregister_without_regexp, :unregister
alias_method :resolve_without_regexp, :resolve
def register(uri, handler)
if uri.is_a?(Regexp)
unless (@regexp_handlers ||= []).any? { |(re,h)| re==uri ? h.concat(handler) : false }
@regexp_handlers << [ uri, handler ]
end
else
# Original behaviour
register_without_regexp(uri, handler)
end
end
def unregister(uri)
if uri.is_a?(Regexp)
raise Mongrel::URIClassifier::RegistrationError, "\#{uri.inspect} was not registered" unless (@regexp_handlers ||= []).reject! { |(re,h)| re==uri }
else
# Original behaviour
unregister_without_regexp(uri)
end
end
def resolve(request_uri)
# Try original behaviour FIRST
result = resolve_without_regexp(request_uri)
# If a match is not found with non-regexp URIs, try regexp
if result[0].blank?
(@regexp_handlers ||= []).any? { |(re,h)| (m = re.match(request_uri)) ? (result = [ m.pre_match + m.to_s, (m.to_s == Mongrel::Const::SLASH ? request_uri : m.post_match), h ]) : false }
end
result
end
EOS
http_server = Mongrel::Configurator.new :host => config.get("http_host") do
listener :port => config.get("http_port") do
# Can pass a regular expression as URI
# (URI must be of type Regexp, no escaping please!)
# Regular expression can match any part of an URL, start with "^/..." to
# anchor match at URI beginning.
# The way this is implemented, regexp matches are only evaluated AFTER
# all non-regexp matches have failed (mostly for performance reasons.)
# Also, for regexp URIs, the :in_front is ignored; adding multiple handlers
# to the same URI regexp behaves as if :in_front => false
uri /^[a-z0-9]+.js/, :handler => BLAH::CustomHandler.new
uri '/ui/public', :handler => Mongrel::DirHandler.new("#{$d}/public/")
uri '/favicon', :handler => Mongrel::Error404Handler.new('')
trap("INT") { stop }
run
end
end
Run Code Online (Sandbox Code Playgroud)
似乎与 Mongrel 1.1.5 配合得很好。