Использование Regex в URI обработчика полукровок

Я в настоящее время использую Полукровку для разработки пользовательского проекта веб-приложения.

Я хотел бы, чтобы Полукровка использовала определенный Обработчик Http на основе регулярного выражения. Например, каждый раз кто-то называет URL как http://test/bla1.js или http://test/bla2.js, которым тот же обработчик 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

Как Вы видите, я пытаюсь использовать regex вместо строки здесь:

 uri Regexp.escape("/[a-z0-9]+.js"), :handler => BLAH::CustomHandler.new

но это не работает. Какое-либо решение?

Спасибо за это.

5
задан Benjamin 27 February 2010 в 04:09
поделиться

2 ответа

Вам придется внедрить новый код в часть 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

Кажется, он отлично работает с Mongrel 1.1.5.

1
ответ дан 15 December 2019 в 06:24
поделиться

Вместо этого вам следует подумать о создании Rack-приложения . Rack - это:

  • стандарт для веб-приложений Ruby
  • , используемый внутри всех популярных веб-фреймворков Ruby ( Rails , Merb , Sinatra ) , Camping , Ramaze , ...)
  • гораздо проще расширить
  • готов к запуску на любом сервере приложений (Mongrel, Webrick, Thin, Passenger, ...)

Rack имеет DSL сопоставления URL-адресов, Rack :: Builder , который позволяет сопоставлять различные приложения Rack с определенными префиксами URL-адресов. Обычно вы сохраняете его как config.ru и запускаете с помощью rackup .

К сожалению, он также не поддерживает регулярные выражения. Но из-за простоты Rack действительно легко написать «приложение» (на самом деле лямбда ), которое будет вызывать правильное приложение, если URL-адрес соответствует определенному регулярному выражению.

В вашем примере ваш config.ru может выглядеть примерно так:

require "my_custom_rack_app" # Whatever provides your MyCustomRackApp.

js_handler = MyCustomRackApp.new

default_handlers = Rack::Builder.new do
  map "/public" do
    run Rack::Directory.new("my_dir/public")
  end

  # Uncomment this to replace Rack::Builder's 404 handler with your own:
  # map "/" do
  #   run lambda { |env|
  #     [404, {"Content-Type" => "text/plain"}, ["My 404 response"]]
  #   }
  # end
end

run lambda { |env|
  if env["PATH_INFO"] =~ %r{/[a-z0-9]+\.js}
    js_handler.call(env)
  else
    default_handlers.call(env)
  end
}

Затем запустите приложение Rack в командной строке:

% rackup

Если у вас установлена ​​mongrel, оно будет запущен на порту 9292. Готово!

2
ответ дан 15 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: