class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 904 def initialize(app = nil) 905 super() 906 @app = app 907 @template_cache = Tilt::Cache.new 908 yield self if block_given? 909 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 939 def self.settings 940 self 941 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1359 def add_filter(type, path = /.*/, **options, &block) 1360 filters[type] << compile!(type, path, block, options) 1361 end
Define an after filter; runs after all requests within the same context as route handlers and may access/modify the request and response.
# File lib/sinatra/base.rb 1354 def after(path = /.*/, **options, &block) 1355 add_filter(:after, path, options, &block) 1356 end
Define a before filter; runs before all requests within the same context as route handlers and may access/modify the request and response.
# File lib/sinatra/base.rb 1347 def before(path = /.*/, **options, &block) 1348 add_filter(:before, path, options, &block) 1349 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1493 def build(app) 1494 builder = Rack::Builder.new 1495 setup_default_middleware builder 1496 setup_middleware builder 1497 builder.run app 1498 builder 1499 end
# File lib/sinatra/base.rb 1501 def call(env) 1502 synchronize { prototype.call(env) } 1503 end
Like Kernel#caller but excluding certain magic entries and without line / method information; the resulting array contains filenames only.
# File lib/sinatra/base.rb 1507 def caller_files 1508 cleaned_caller(1).flatten 1509 end
Like caller_files
, but containing Arrays rather than strings with the first element being the file, and the second being the line.
# File lib/sinatra/base.rb 1513 def caller_locations 1514 cleaned_caller 2 1515 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1739 def cleaned_caller(keep = 3) 1740 caller(1). 1741 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1742 reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } 1743 end
# File lib/sinatra/base.rb 1640 def compile(path, route_mustermann_opts = {}) 1641 Mustermann.new(path, mustermann_opts.merge(route_mustermann_opts)) 1642 end
# File lib/sinatra/base.rb 1621 def compile!(verb, path, block, **options) 1622 # Because of self.options.host 1623 host_name(options.delete(:host)) if options.key?(:host) 1624 # Pass Mustermann opts to compile() 1625 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1626 1627 options.each_pair { |option, args| send(option, *args) } 1628 1629 pattern = compile(path, route_mustermann_opts) 1630 method_name = "#{verb} #{path}" 1631 unbound_method = generate_method(method_name, &block) 1632 conditions, @conditions = @conditions, [] 1633 wrapper = block.arity != 0 ? 1634 proc { |a, p| unbound_method.bind(a).call(*p) } : 1635 proc { |a, p| unbound_method.bind(a).call } 1636 1637 [ pattern, conditions, wrapper ] 1638 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1365 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1366 @conditions << generate_method(name, &block) 1367 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1425 def configure(*envs) 1426 yield self if envs.empty? || envs.include?(environment.to_sym) 1427 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1559 def define_singleton(name, content = Proc.new) 1560 singleton_class.class_eval do 1561 undef_method(name) if method_defined? name 1562 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1563 end 1564 end
# File lib/sinatra/base.rb 1394 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1707 def detect_rack_handler 1708 servers = Array(server) 1709 servers.each do |server_name| 1710 begin 1711 return Rack::Handler.get(server_name.to_s) 1712 rescue LoadError, NameError 1713 end 1714 end 1715 fail "Server handler (#{servers.join(',')}) not found." 1716 end
# File lib/sinatra/base.rb 1419 def development?; environment == :development end
Same as calling `set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1263 def disable(*opts) 1264 opts.each { |key| set(key, false) } 1265 end
Same as calling `set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1258 def enable(*opts) 1259 opts.each { |key| set(key, true) } 1260 end
Define a custom error handler. Optionally takes either an Exception class, or an HTTP status code to specify which errors should be handled.
# File lib/sinatra/base.rb 1270 def error(*codes, &block) 1271 args = compile! "ERROR", /.*/, block 1272 codes = codes.flat_map(&method(:Array)) 1273 codes << Exception if codes.empty? 1274 codes << Sinatra::NotFound if codes.include?(404) 1275 codes.each { |c| (@errors[c] ||= []) << args } 1276 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1203 def extensions 1204 if superclass.respond_to?(:extensions) 1205 (@extensions + superclass.extensions).uniq 1206 else 1207 @extensions 1208 end 1209 end
# File lib/sinatra/base.rb 1754 def self.force_encoding(data, encoding = default_encoding) 1755 return if data == settings || data.is_a?(Tempfile) 1756 if data.respond_to? :force_encoding 1757 data.force_encoding(encoding).encode! 1758 elsif data.respond_to? :each_value 1759 data.each_value { |v| force_encoding(v, encoding) } 1760 elsif data.respond_to? :each 1761 data.each { |v| force_encoding(v, encoding) } 1762 end 1763 data 1764 end
# File lib/sinatra/base.rb 1614 def generate_method(method_name, &block) 1615 define_method(method_name, &block) 1616 method = instance_method method_name 1617 remove_method method_name 1618 method 1619 end
Defining a `GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1384 def get(path, opts = {}, &block) 1385 conditions = @conditions.dup 1386 route('GET', path, opts, &block) 1387 1388 @conditions = conditions 1389 route('HEAD', path, opts, &block) 1390 end
# File lib/sinatra/base.rb 1395 def head(path, opts = {}, &bk) route 'HEAD', path, opts, &bk end
Makes the methods defined in the block and in the Modules given in `extensions` available to the handlers and templates
# File lib/sinatra/base.rb 1403 def helpers(*extensions, &block) 1404 class_eval(&block) if block_given? 1405 include(*extensions) if extensions.any? 1406 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1567 def host_name(pattern) 1568 condition { pattern === request.host } 1569 end
# File lib/sinatra/base.rb 1718 def inherited(subclass) 1719 subclass.reset! 1720 subclass.set :app_file, caller_files.first unless subclass.app_file? 1721 super 1722 end
Load embedded templates from the file; uses the caller's __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1296 def inline_templates=(file = nil) 1297 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1298 1299 begin 1300 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1301 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1302 rescue Errno::ENOENT 1303 app, data = nil 1304 end 1305 1306 if data 1307 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1308 encoding = $2 1309 else 1310 encoding = settings.default_encoding 1311 end 1312 lines = app.count("\n") + 1 1313 template = nil 1314 force_encoding data, encoding 1315 data.each_line do |line| 1316 lines += 1 1317 if line =~ /^@@\s*(.*\S)\s*$/ 1318 template = force_encoding(String.new, encoding) 1319 templates[$1.to_sym] = [template, file, lines] 1320 elsif template 1321 template << line 1322 end 1323 end 1324 end 1325 end
# File lib/sinatra/base.rb 1610 def invoke_hook(name, *args) 1611 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1612 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1290 def layout(name = :layout, &block) 1291 template name, &block 1292 end
# File lib/sinatra/base.rb 1398 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1212 def middleware 1213 if superclass.respond_to?(:middleware) 1214 superclass.middleware + @middleware 1215 else 1216 @middleware 1217 end 1218 end
Lookup or register a mime type in Rack's mime registry.
# File lib/sinatra/base.rb 1328 def mime_type(type, value = nil) 1329 return type if type.nil? 1330 return type.to_s if type.to_s.include?('/') 1331 type = ".#{type}" unless type.to_s[0] == ?. 1332 return Rack::Mime.mime_type(type, nil) unless value 1333 Rack::Mime::MIME_TYPES[type] = value 1334 end
provides all mime types matching type, including deprecated types:
mime_types :html # => ['text/html'] mime_types :js # => ['application/javascript', 'text/javascript']
# File lib/sinatra/base.rb 1339 def mime_types(type) 1340 type = mime_type type 1341 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1342 end
Create a new instance of the class fronted by its middleware pipeline. The object is guaranteed to respond to call
but may not be an instance of the class new was called on.
# File lib/sinatra/base.rb 1486 def new(*args, &bk) 1487 instance = new!(*args, &bk) 1488 Wrapper.new(build(instance).to_app, instance) 1489 end
Sugar for `error(404) { … }`
# File lib/sinatra/base.rb 1279 def not_found(&block) 1280 error(404, &block) 1281 end
# File lib/sinatra/base.rb 1396 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1397 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1393 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1420 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1476 def prototype 1477 @prototype ||= new 1478 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1586 def provides(*types) 1587 types.map! { |t| mime_types(t) } 1588 types.flatten! 1589 condition do 1590 if type = response['Content-Type'] 1591 types.include? type or types.include? type[/^[^;]+/] 1592 elsif type = request.preferred_type(types) 1593 params = (type.respond_to?(:params) ? type.params : {}) 1594 content_type(type, params) 1595 true 1596 else 1597 false 1598 end 1599 end 1600 end
# File lib/sinatra/base.rb 1369 def public=(value) 1370 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1371 set(:public_folder, value) 1372 end
# File lib/sinatra/base.rb 1378 def public_dir 1379 public_folder 1380 end
# File lib/sinatra/base.rb 1374 def public_dir=(value) 1375 self.public_folder = value 1376 end
# File lib/sinatra/base.rb 1392 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1436 def quit! 1437 return unless running? 1438 # Use Thin's hard #stop! if available, otherwise just #stop. 1439 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1440 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1441 set :running_server, nil 1442 set :handler_name, nil 1443 end
Register an extension. Alternatively take a block from which an extension will be created and registered on the fly.
# File lib/sinatra/base.rb 1410 def register(*extensions, &block) 1411 extensions << Module.new(&block) if block_given? 1412 @extensions += extensions 1413 extensions.each do |extension| 1414 extend extension 1415 extension.registered(self) if extension.respond_to?(:registered) 1416 end 1417 end
Removes all routes, filters, middleware and extension hooks from the current class (not routes/filters/… defined by its superclass).
# File lib/sinatra/base.rb 1186 def reset! 1187 @conditions = [] 1188 @routes = {} 1189 @filters = {:before => [], :after => []} 1190 @errors = {} 1191 @middleware = [] 1192 @prototype = nil 1193 @extensions = [] 1194 1195 if superclass.respond_to?(:templates) 1196 @templates = Hash.new { |hash, key| superclass.templates[key] } 1197 else 1198 @templates = {} 1199 end 1200 end
# File lib/sinatra/base.rb 1602 def route(verb, path, options = {}, &block) 1603 enable :empty_path_info if path == "" and empty_path_info.nil? 1604 signature = compile!(verb, path, block, options) 1605 (@routes[verb] ||= []) << signature 1606 invoke_hook(:route_added, verb, path, block) 1607 signature 1608 end
Run the Sinatra
app as a self-hosted server using Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, will call with the constructed handler once we have taken the stage.
# File lib/sinatra/base.rb 1450 def run!(options = {}, &block) 1451 return if running? 1452 set options 1453 handler = detect_rack_handler 1454 handler_name = handler.name.gsub(/.*::/, '') 1455 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1456 server_settings.merge!(:Port => port, :Host => bind) 1457 1458 begin 1459 start_server(handler, server_settings, handler_name, &block) 1460 rescue Errno::EADDRINUSE 1461 $stderr.puts "== Someone is already performing on port #{port}!" 1462 raise 1463 ensure 1464 quit! 1465 end 1466 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1471 def running? 1472 running_server? 1473 end
Sets an option to the given value. If the value is a proc, the proc will be called every time the option is accessed.
# File lib/sinatra/base.rb 1222 def set(option, value = (not_set = true), ignore_setter = false, &block) 1223 raise ArgumentError if block and !not_set 1224 value, not_set = block, false if block 1225 1226 if not_set 1227 raise ArgumentError unless option.respond_to?(:each) 1228 option.each { |k,v| set(k, v) } 1229 return self 1230 end 1231 1232 if respond_to?("#{option}=") and not ignore_setter 1233 return __send__("#{option}=", value) 1234 end 1235 1236 setter = proc { |val| set option, val, true } 1237 getter = proc { value } 1238 1239 case value 1240 when Proc 1241 getter = value 1242 when Symbol, Integer, FalseClass, TrueClass, NilClass 1243 getter = value.inspect 1244 when Hash 1245 setter = proc do |val| 1246 val = value.merge val if Hash === val 1247 set option, val, true 1248 end 1249 end 1250 1251 define_singleton("#{option}=", setter) 1252 define_singleton(option, getter) 1253 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1254 self 1255 end
# File lib/sinatra/base.rb 1671 def setup_common_logger(builder) 1672 builder.use Sinatra::CommonLogger 1673 end
# File lib/sinatra/base.rb 1675 def setup_custom_logger(builder) 1676 if logging.respond_to? :to_int 1677 builder.use Rack::Logger, logging 1678 else 1679 builder.use Rack::Logger 1680 end 1681 end
# File lib/sinatra/base.rb 1644 def setup_default_middleware(builder) 1645 builder.use ExtendedRack 1646 builder.use ShowExceptions if show_exceptions? 1647 builder.use Rack::MethodOverride if method_override? 1648 builder.use Rack::Head 1649 setup_logging builder 1650 setup_sessions builder 1651 setup_protection builder 1652 end
# File lib/sinatra/base.rb 1658 def setup_logging(builder) 1659 if logging? 1660 setup_common_logger(builder) 1661 setup_custom_logger(builder) 1662 elsif logging == false 1663 setup_null_logger(builder) 1664 end 1665 end
# File lib/sinatra/base.rb 1654 def setup_middleware(builder) 1655 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1656 end
# File lib/sinatra/base.rb 1667 def setup_null_logger(builder) 1668 builder.use Rack::NullLogger 1669 end
# File lib/sinatra/base.rb 1683 def setup_protection(builder) 1684 return unless protection? 1685 options = Hash === protection ? protection.dup : {} 1686 options = { 1687 img_src: "'self' data:", 1688 font_src: "'self'" 1689 }.merge options 1690 1691 protect_session = options.fetch(:session) { sessions? } 1692 options[:without_session] = !protect_session 1693 1694 options[:reaction] ||= :drop_session 1695 1696 builder.use Rack::Protection, options 1697 end
# File lib/sinatra/base.rb 1699 def setup_sessions(builder) 1700 return unless sessions? 1701 options = {} 1702 options[:secret] = session_secret if session_secret? 1703 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1704 builder.use session_store, options 1705 end
# File lib/sinatra/base.rb 1543 def setup_traps 1544 if traps? 1545 at_exit { quit! } 1546 1547 [:INT, :TERM].each do |signal| 1548 old_handler = trap(signal) do 1549 quit! 1550 old_handler.call if old_handler.respond_to?(:call) 1551 end 1552 end 1553 1554 set :traps, false 1555 end 1556 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1520 def start_server(handler, server_settings, handler_name) 1521 # Ensure we initialize middleware before startup, to match standard Rack 1522 # behavior, by ensuring an instance exists: 1523 prototype 1524 # Run the instance we created: 1525 handler.run(self, server_settings) do |server| 1526 unless suppress_messages? 1527 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1528 end 1529 1530 setup_traps 1531 set :running_server, server 1532 set :handler_name, handler_name 1533 server.threaded = settings.threaded if server.respond_to? :threaded= 1534 1535 yield server if block_given? 1536 end 1537 end
# File lib/sinatra/base.rb 1539 def suppress_messages? 1540 handler_name =~ /cgi/i || quiet 1541 end
# File lib/sinatra/base.rb 1725 def synchronize(&block) 1726 if lock? 1727 @@mutex.synchronize(&block) 1728 else 1729 yield 1730 end 1731 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1284 def template(name, &block) 1285 filename, line = caller_locations.first 1286 templates[name] = [block, filename, line.to_i] 1287 end
# File lib/sinatra/base.rb 1421 def test?; environment == :test end
# File lib/sinatra/base.rb 1399 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1430 def use(middleware, *args, &block) 1431 @prototype = nil 1432 @middleware << [middleware, args, block] 1433 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1573 def user_agent(pattern) 1574 condition do 1575 if request.user_agent.to_s =~ pattern 1576 @params[:agent] = $~[1..-1] 1577 true 1578 else 1579 false 1580 end 1581 end 1582 end
used for deprecation warnings
# File lib/sinatra/base.rb 1734 def warn(message) 1735 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1736 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 912 def call(env) 913 dup.call!(env) 914 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 969 def forward 970 fail "downstream app not set" unless @app.respond_to? :call 971 status, headers, body = @app.call env 972 @response.status = status 973 @response.body = body 974 @response.headers.merge! headers 975 nil 976 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 956 def halt(*response) 957 response = response.first if response.length == 1 958 throw :halt, response 959 end
# File lib/sinatra/base.rb 948 def options 949 warn "Sinatra::Base#options is deprecated and will be removed, " \ 950 "use #settings instead." 951 settings 952 end
Pass control to the next matching route. If there are no more matching routes, Sinatra
will return a 404 response.
# File lib/sinatra/base.rb 964 def pass(&block) 965 throw :pass, block 966 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 944 def settings 945 self.class.settings 946 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1091 def dispatch! 1092 force_encoding(@params.merge!(@request.params)) 1093 1094 invoke do 1095 static! if settings.static? && (request.get? || request.head?) 1096 filter! :before 1097 route! 1098 end 1099 rescue ::Exception => boom 1100 invoke { handle_exception!(boom) } 1101 ensure 1102 begin 1103 filter! :after unless env['sinatra.static_file'] 1104 rescue ::Exception => boom 1105 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1106 end 1107 end
# File lib/sinatra/base.rb 1159 def dump_errors!(boom) 1160 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1161 @env['rack.errors'].puts(msg) 1162 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1144 def error_block!(key, *block_params) 1145 base = settings 1146 while base.respond_to?(:errors) 1147 next base = base.superclass unless args_array = base.errors[key] 1148 args_array.reverse_each do |args| 1149 first = args == args_array.first 1150 args += [block_params] 1151 resp = process_route(*args) 1152 return resp unless resp.nil? && !first 1153 end 1154 end 1155 return false unless key.respond_to? :superclass and key.superclass < Exception 1156 error_block!(key.superclass, *block_params) 1157 end
Run filters defined on the class and all superclasses.
# File lib/sinatra/base.rb 981 def filter!(type, base = settings) 982 filter! type, base.superclass if base.superclass.respond_to?(:filters) 983 base.filters[type].each { |args| process_route(*args) } 984 end
Fixes encoding issues by
-
defaulting to UTF-8
-
casting params to Encoding.default_external
The latter might not be necessary if Rack
handles it one day. Keep an eye on Rack's LH #100.
# File lib/sinatra/base.rb 1752 def force_encoding(*args) settings.force_encoding(*args) end
Error handling during requests.
# File lib/sinatra/base.rb 1110 def handle_exception!(boom) 1111 if error_params = @env['sinatra.error.params'] 1112 @params = @params.merge(error_params) 1113 end 1114 @env['sinatra.error'] = boom 1115 1116 if boom.respond_to? :http_status 1117 status(boom.http_status) 1118 elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599 1119 status(boom.code) 1120 else 1121 status(500) 1122 end 1123 1124 status(500) unless status.between? 400, 599 1125 1126 boom_message = boom.message if boom.message && boom.message != boom.class.name 1127 if server_error? 1128 dump_errors! boom if settings.dump_errors? 1129 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1130 elsif not_found? 1131 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1132 body boom_message || '<h1>Not Found</h1>' 1133 elsif bad_request? 1134 body boom_message || '<h1>Bad Request</h1>' 1135 end 1136 1137 res = error_block!(boom.class, boom) || error_block!(status, boom) 1138 return res if res or not server_error? 1139 raise boom if settings.raise_errors? or settings.show_exceptions? 1140 error_block! Exception, boom 1141 end
Run the block with 'throw :halt' support and apply result to the response.
# File lib/sinatra/base.rb 1075 def invoke 1076 res = catch(:halt) { yield } 1077 1078 res = [res] if Integer === res or String === res 1079 if Array === res and Integer === res.first 1080 res = res.dup 1081 status(res.shift) 1082 body(res.pop) 1083 headers(*res) 1084 elsif res.respond_to? :each 1085 body res 1086 end 1087 nil # avoid double setting the same response tuple twice 1088 end
If the current request matches pattern and conditions, fill params with keys and call the given block. Revert params afterwards.
Returns pass block.
# File lib/sinatra/base.rb 1019 def process_route(pattern, conditions, block = nil, values = []) 1020 route = @request.path_info 1021 route = '/' if route.empty? and not settings.empty_path_info? 1022 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1023 return unless params = pattern.params(route) 1024 1025 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1026 force_encoding(params) 1027 original, @params = @params, @params.merge(params) if params.any? 1028 1029 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1030 if regexp_exists 1031 captures = pattern.match(route).captures 1032 values += captures 1033 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1034 else 1035 values += params.values.flatten 1036 end 1037 1038 catch(:pass) do 1039 conditions.each { |c| throw :pass if c.bind(self).call == false } 1040 block ? block[self, values] : yield(self, values) 1041 end 1042 rescue 1043 @env['sinatra.error.params'] = @params 1044 raise 1045 ensure 1046 @params = original if original 1047 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 987 def route!(base = settings, pass_block = nil) 988 if routes = base.routes[@request.request_method] 989 routes.each do |pattern, conditions, block| 990 returned_pass_block = process_route(pattern, conditions) do |*args| 991 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 992 route_eval { block[*args] } 993 end 994 995 # don't wipe out pass_block in superclass 996 pass_block = returned_pass_block if returned_pass_block 997 end 998 end 999 1000 # Run routes defined in superclass. 1001 if base.superclass.respond_to?(:routes) 1002 return route!(base.superclass, pass_block) 1003 end 1004 1005 route_eval(&pass_block) if pass_block 1006 route_missing 1007 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1010 def route_eval 1011 throw :halt, yield 1012 end
No matching route was found or all routes passed. The default implementation is to forward the request downstream when running as middleware (@app is non-nil); when no downstream app is set, raise a NotFound
exception. Subclasses can override this method to perform custom route miss logic.
# File lib/sinatra/base.rb 1054 def route_missing 1055 if @app 1056 forward 1057 else 1058 raise NotFound 1059 end 1060 end
Attempt to serve static files from public directory. Throws :halt when a matching file is found, returns nil otherwise.
# File lib/sinatra/base.rb 1064 def static!(options = {}) 1065 return if (public_dir = settings.public_folder).nil? 1066 path = File.expand_path("#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" ) 1067 return unless File.file?(path) 1068 1069 env['sinatra.static_file'] = path 1070 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1071 send_file path, options.merge(:disposition => nil) 1072 end