mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
Expose global and per-route Mustermann options
This commit is contained in:
parent
004daf4922
commit
910a9f72a8
3 changed files with 46 additions and 9 deletions
20
README.md
20
README.md
|
@ -257,6 +257,20 @@ end
|
|||
By the way, unless you disable the path traversal attack protection (see below),
|
||||
the request path might be modified before matching against your routes.
|
||||
|
||||
You may customize the Mustermann options used for a given route by passing in a
|
||||
`:mustermann_opts` hash:
|
||||
|
||||
```ruby
|
||||
get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
|
||||
# matches /posts exactly, with explicit anchoring
|
||||
"If you match an anchored pattern clap your hands!"
|
||||
end
|
||||
```
|
||||
|
||||
It looks like a [condition](#conditions), but it isn't one! These options will
|
||||
be merged into the global `:mustermann_opts` hash described
|
||||
[below](#available-settings).
|
||||
|
||||
## Conditions
|
||||
|
||||
Routes may include a variety of matching conditions, such as the user agent:
|
||||
|
@ -2254,6 +2268,12 @@ set :protection, :session => true
|
|||
don't support it.
|
||||
</dd>
|
||||
|
||||
<dt>mustermann_opts</dt>
|
||||
<dd>
|
||||
A default hash of options to pass to Mustermann.new when compiling routing
|
||||
paths.
|
||||
</dd>
|
||||
|
||||
<dt>port</dt>
|
||||
<dd>Port to listen on. Only used for built-in server.</dd>
|
||||
|
||||
|
|
|
@ -1607,8 +1607,6 @@ module Sinatra
|
|||
end
|
||||
|
||||
def route(verb, path, options = {}, &block)
|
||||
# Because of self.options.host
|
||||
host_name(options.delete(:host)) if options.key?(:host)
|
||||
enable :empty_path_info if path == "" and empty_path_info.nil?
|
||||
signature = compile!(verb, path, block, options)
|
||||
(@routes[verb] ||= []) << signature
|
||||
|
@ -1628,9 +1626,14 @@ module Sinatra
|
|||
end
|
||||
|
||||
def compile!(verb, path, block, **options)
|
||||
# Because of self.options.host
|
||||
host_name(options.delete(:host)) if options.key?(:host)
|
||||
# Pass Mustermann opts to compile()
|
||||
route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze
|
||||
|
||||
options.each_pair { |option, args| send(option, *args) }
|
||||
|
||||
pattern = compile(path)
|
||||
pattern = compile(path, route_mustermann_opts)
|
||||
method_name = "#{verb} #{path}"
|
||||
unbound_method = generate_method(method_name, &block)
|
||||
conditions, @conditions = @conditions, []
|
||||
|
@ -1641,8 +1644,8 @@ module Sinatra
|
|||
[ pattern, conditions, wrapper ]
|
||||
end
|
||||
|
||||
def compile(path)
|
||||
Mustermann.new(path)
|
||||
def compile(path, route_mustermann_opts = {})
|
||||
Mustermann.new(path, mustermann_opts.merge(route_mustermann_opts))
|
||||
end
|
||||
|
||||
def setup_default_middleware(builder)
|
||||
|
@ -1786,6 +1789,7 @@ module Sinatra
|
|||
set :x_cascade, true
|
||||
set :add_charset, %w[javascript xml xhtml+xml].map { |t| "application/#{t}" }
|
||||
settings.add_charset << /^text\//
|
||||
set :mustermann_opts, {}
|
||||
|
||||
# explicitly generating a session secret eagerly to play nice with preforking
|
||||
begin
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
require File.expand_path('../helper', __FILE__)
|
||||
|
||||
class CompileTest < Minitest::Test
|
||||
def self.parses pattern, example, expected_params
|
||||
def self.parses pattern, example, expected_params, mtype = :sinatra, mopts = {}
|
||||
it "parses #{example} with #{pattern} into params #{expected_params}" do
|
||||
compiled = mock_app {}.send(:compile, pattern)
|
||||
compiled = mock_app { set :mustermann_opts, :type => mtype }.send(:compile, pattern, mopts)
|
||||
params = compiled.params(example)
|
||||
fail %Q{"#{example}" does not parse on pattern "#{pattern}".} unless params
|
||||
|
||||
|
@ -12,14 +12,22 @@ class CompileTest < Minitest::Test
|
|||
end
|
||||
end
|
||||
|
||||
def self.fails pattern, example
|
||||
def self.fails pattern, example, mtype = :sinatra, mopts = {}
|
||||
it "does not parse #{example} with #{pattern}" do
|
||||
compiled = mock_app {}.send(:compile, pattern)
|
||||
compiled = mock_app { set :mustermann_opts, :type => mtype }.send(:compile, pattern, mopts)
|
||||
match = compiled.match(example)
|
||||
fail %Q{"#{pattern}" does parse "#{example}" but it should fail} if match
|
||||
end
|
||||
end
|
||||
|
||||
def self.raises pattern, mtype = :sinatra, mopts = {}
|
||||
it "does not compile #{pattern}" do
|
||||
assert_raises(Mustermann::CompileError, %Q{Pattern "#{pattern}" compiles but it should not}) do
|
||||
mock_app { set :mustermann_opts, :type => mtype }.send(:compile, pattern, mopts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
parses "/", "/", {}
|
||||
|
||||
parses "/foo", "/foo", {}
|
||||
|
@ -129,4 +137,9 @@ class CompileTest < Minitest::Test
|
|||
# From issue #688.
|
||||
#
|
||||
parses "/articles/10.1103/:doi", "/articles/10.1103/PhysRevLett.110.026401", "doi" => "PhysRevLett.110.026401"
|
||||
|
||||
# Mustermann anchoring
|
||||
fails "/bar", "/foo/bar", :regexp
|
||||
raises "^/foo/bar$", :regexp
|
||||
parses "^/foo/bar$", "/foo/bar", {}, :regexp, :check_anchors => false
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue