2010-02-27 13 views
5

मैं वर्तमान में कस्टम वेब एप्लिकेशन प्रोजेक्ट विकसित करने के लिए Mongrel का उपयोग कर रहा हूं।एक मोंगेल हैंडलर के यूआरआई में एक रेगेक्स का उपयोग

मैं चाहता हूं कि मंगलेल नियमित अभिव्यक्ति के आधार पर परिभाषित एचटीपी हैंडलर का उपयोग करे। उदाहरण के लिए, हर बार जब कोई यूआरएल http://test/bla1.js या http://test/bla2.js कहता है तो उसी एचटीपी हैंडलर को अनुरोध का प्रबंधन करने के लिए बुलाया जाता है।

मेरे कोड अब तक ऐसा दिखता है जैसे एक:

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 

लेकिन वह काम नहीं करता । कोई भी समाधान?

इसके लिए धन्यवाद।

उत्तर

1

आपको Mongrel के URIClassifier के हिस्से में नया कोड इंजेक्ट करना होगा, जो अन्यथा नियमित रूप से अभिव्यक्ति यूआरआई से अनजान है।

# 
# 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 

संकर जाति 1.1.5 के साथ अच्छे से कार्य करती लगता है:

नीचे सिर्फ इतना है कि ऐसा करने का एक तरीका है।

+0

धन्यवाद। यही वही है जो मुझे चाहिए था। – Benjamin

2

आपको इसके बजाय Rack application बनाने पर विचार करना चाहिए। रैक है:

  • रूबी वेब अनुप्रयोगों के लिए मानक
  • सभी लोकप्रिय रूबी वेब चौखटे द्वारा आंतरिक रूप से उपयोग (Rails, Merb, Sinatra, Camping, Ramaze, ...)
  • बहुत आसान विस्तार करने के लिए
  • पर चलाने के लिए तैयार एप्लिकेशन सर्वर (Mongrel, Webrick, Thin, यात्री, ...)

रैक में एक यूआरएल मैपिंग डीएसएल, Rack::Builder है, जो आपको विभिन्न यूआरएल उपसर्गों के लिए विभिन्न रैक अनुप्रयोगों को मैप करने की अनुमति देता है। आप इसे आमतौर पर config.ru के रूप में सहेजते हैं, और इसे rackup के साथ चलाते हैं।

दुर्भाग्यवश, यह नियमित अभिव्यक्तियों की अनुमति नहीं देता है। लेकिन रैक की सादगी के कारण, "एप्लिकेशन" (वास्तव में lambda, वास्तव में) लिखना वास्तव में आसान है जो यूआरएल एक निश्चित रेगेक्स से मेल खाता है तो उचित ऐप कॉल करेगा।

अपने उदाहरण के आधार पर, अपने 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 
} 

इसके बाद, कमांड लाइन पर अपने रैक अनुप्रयोग चलाने:

% rackup 

आप संकर जाति का स्थापित किया है, कहीं भी होगी पोर्ट 9 2 9 2 पर शुरू किया जाना चाहिए। हो गया!

+0

उस उत्तर के लिए धन्यवाद। – Benjamin

संबंधित मुद्दे