tennpipes-base 3.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +294 -0
- data/Rakefile +1 -0
- data/bin/tennpipes +8 -0
- data/lib/tennpipes-base.rb +196 -0
- data/lib/tennpipes-base/application.rb +175 -0
- data/lib/tennpipes-base/application/application_setup.rb +202 -0
- data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
- data/lib/tennpipes-base/application/flash.rb +229 -0
- data/lib/tennpipes-base/application/params_protection.rb +129 -0
- data/lib/tennpipes-base/application/routing.rb +1002 -0
- data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
- data/lib/tennpipes-base/caller.rb +53 -0
- data/lib/tennpipes-base/cli/adapter.rb +33 -0
- data/lib/tennpipes-base/cli/base.rb +105 -0
- data/lib/tennpipes-base/cli/console.rb +20 -0
- data/lib/tennpipes-base/cli/launcher.rb +103 -0
- data/lib/tennpipes-base/cli/rake.rb +50 -0
- data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
- data/lib/tennpipes-base/command.rb +38 -0
- data/lib/tennpipes-base/ext/sinatra.rb +29 -0
- data/lib/tennpipes-base/filter.rb +52 -0
- data/lib/tennpipes-base/images/404.png +0 -0
- data/lib/tennpipes-base/images/500.png +0 -0
- data/lib/tennpipes-base/loader.rb +202 -0
- data/lib/tennpipes-base/logger.rb +492 -0
- data/lib/tennpipes-base/module.rb +58 -0
- data/lib/tennpipes-base/mounter.rb +308 -0
- data/lib/tennpipes-base/path_router.rb +119 -0
- data/lib/tennpipes-base/path_router/compiler.rb +110 -0
- data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
- data/lib/tennpipes-base/path_router/matcher.rb +123 -0
- data/lib/tennpipes-base/path_router/route.rb +169 -0
- data/lib/tennpipes-base/reloader.rb +309 -0
- data/lib/tennpipes-base/reloader/rack.rb +26 -0
- data/lib/tennpipes-base/reloader/storage.rb +55 -0
- data/lib/tennpipes-base/router.rb +98 -0
- data/lib/tennpipes-base/server.rb +119 -0
- data/lib/tennpipes-base/tasks.rb +21 -0
- data/lib/tennpipes-base/version.rb +20 -0
- data/lib/tennpipes-base/version.rb~ +20 -0
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/fixtures/apps/complex.rb +32 -0
- data/test/fixtures/apps/demo_app.rb +7 -0
- data/test/fixtures/apps/demo_demo.rb +7 -0
- data/test/fixtures/apps/demo_project/api/app.rb +7 -0
- data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
- data/test/fixtures/apps/demo_project/app.rb +7 -0
- data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
- data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
- data/test/fixtures/apps/mountable_apps/static.html +1 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/simple.rb +32 -0
- data/test/fixtures/apps/static.rb +10 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
- data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
- data/test/fixtures/dependencies/a.rb +9 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/fixtures/dependencies/circular/e.rb +13 -0
- data/test/fixtures/dependencies/circular/f.rb +2 -0
- data/test/fixtures/dependencies/circular/g.rb +2 -0
- data/test/fixtures/dependencies/d.rb +4 -0
- data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
- data/test/fixtures/reloadable_apps/main/app.rb +10 -0
- data/test/helper.rb +30 -0
- data/test/test_application.rb +185 -0
- data/test/test_core.rb +93 -0
- data/test/test_csrf_protection.rb +208 -0
- data/test/test_dependencies.rb +57 -0
- data/test/test_filters.rb +389 -0
- data/test/test_flash.rb +168 -0
- data/test/test_locale.rb +21 -0
- data/test/test_logger.rb +295 -0
- data/test/test_mounter.rb +302 -0
- data/test/test_params_protection.rb +195 -0
- data/test/test_reloader_complex.rb +74 -0
- data/test/test_reloader_external.rb +21 -0
- data/test/test_reloader_simple.rb +101 -0
- data/test/test_reloader_system.rb +113 -0
- data/test/test_restful_routing.rb +33 -0
- data/test/test_router.rb +281 -0
- data/test/test_routing.rb +2328 -0
- metadata +301 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
module Reloader
|
3
|
+
##
|
4
|
+
# This class acts as a Rack middleware to be added to the application stack.
|
5
|
+
# This middleware performs a check and reload for source files at the start
|
6
|
+
# of each request, but also respects a specified cool down time
|
7
|
+
# during which no further action will be taken.
|
8
|
+
#
|
9
|
+
class Rack
|
10
|
+
def initialize(app, cooldown=1)
|
11
|
+
@app = app
|
12
|
+
@cooldown = cooldown
|
13
|
+
@last = (Time.now - cooldown)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Invoked in order to perform the reload as part of the request stack.
|
17
|
+
def call(env)
|
18
|
+
if @cooldown && Time.now > @last + @cooldown
|
19
|
+
Thread.list.size > 1 ? Thread.exclusive { Tennpipes.reload! } : Tennpipes.reload!
|
20
|
+
@last = Time.now
|
21
|
+
end
|
22
|
+
@app.call(env)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
module Reloader
|
3
|
+
module Storage
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def clear!
|
7
|
+
files.each_key do |file|
|
8
|
+
remove(file)
|
9
|
+
Reloader.remove_feature(file)
|
10
|
+
end
|
11
|
+
@files = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove(name)
|
15
|
+
file = files[name] || return
|
16
|
+
file[:constants].each{ |constant| Reloader.remove_constant(constant) }
|
17
|
+
file[:features].each{ |feature| Reloader.remove_feature(feature) }
|
18
|
+
files.delete(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def prepare(name)
|
22
|
+
file = remove(name)
|
23
|
+
@old_entries ||= {}
|
24
|
+
@old_entries[name] = {
|
25
|
+
:constants => ObjectSpace.classes,
|
26
|
+
:features => old_features = Set.new($LOADED_FEATURES.dup)
|
27
|
+
}
|
28
|
+
features = file && file[:features] || []
|
29
|
+
features.each{ |feature| Reloader.safe_load(feature, :force => true) }
|
30
|
+
Reloader.remove_feature(name) if old_features.include?(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def commit(name)
|
34
|
+
entry = {
|
35
|
+
:constants => ObjectSpace.new_classes(@old_entries[name][:constants]),
|
36
|
+
:features => Set.new($LOADED_FEATURES) - @old_entries[name][:features] - [name]
|
37
|
+
}
|
38
|
+
files[name] = entry
|
39
|
+
@old_entries.delete(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def rollback(name)
|
43
|
+
new_constants = ObjectSpace.new_classes(@old_entries[name][:constants])
|
44
|
+
new_constants.each{ |klass| Reloader.remove_constant(klass) }
|
45
|
+
@old_entries.delete(name)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def files
|
51
|
+
@files ||= {}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
##
|
3
|
+
# This class is an extended version of Rack::URLMap.
|
4
|
+
#
|
5
|
+
# Tennpipes::Router like Rack::URLMap dispatches in such a way that the
|
6
|
+
# longest paths are tried first, since they are most specific.
|
7
|
+
#
|
8
|
+
# Features:
|
9
|
+
#
|
10
|
+
# * Map a path to the specified App
|
11
|
+
# * Ignore server names (this solve issues with vhost and domain aliases)
|
12
|
+
# * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases)
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# routes = Tennpipes::Router.new do
|
17
|
+
# map(:path => "/", :to => TennpipesWeb, :host => "tennpipes.local")
|
18
|
+
# map(:path => "/", :to => Admin, :host => "admin.tennpipes.local")
|
19
|
+
# end
|
20
|
+
# run routes
|
21
|
+
#
|
22
|
+
# routes = Tennpipes::Router.new do
|
23
|
+
# map(:path => "/", :to => TennpipesWeb, :host => /*.tennpipes.local/)
|
24
|
+
# end
|
25
|
+
# run routes
|
26
|
+
#
|
27
|
+
# @api semipublic
|
28
|
+
class Router
|
29
|
+
def initialize(*mapping, &block)
|
30
|
+
@mapping = []
|
31
|
+
mapping.each { |m| map(m) }
|
32
|
+
instance_eval(&block) if block
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Map a route path and host to a specified application.
|
37
|
+
#
|
38
|
+
# @param [Hash] options
|
39
|
+
# The options to map.
|
40
|
+
# @option options [Sinatra::Application] :to
|
41
|
+
# The class of the application to mount.
|
42
|
+
# @option options [String] :path ("/")
|
43
|
+
# The path to map the specified application.
|
44
|
+
# @option options [String] :host
|
45
|
+
# The host to map the specified application.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# map(:path => "/", :to => TennpipesWeb, :host => "tennpipes.local")
|
49
|
+
#
|
50
|
+
# @return [Array] The sorted route mappings.
|
51
|
+
# @api semipublic
|
52
|
+
def map(options={})
|
53
|
+
path = options[:path] || "/"
|
54
|
+
host = options[:host]
|
55
|
+
app = options[:to]
|
56
|
+
|
57
|
+
raise ArgumentError, "paths need to start with /" if path[0] != ?/
|
58
|
+
raise ArgumentError, "app is required" if app.nil?
|
59
|
+
|
60
|
+
path = path.chomp('/')
|
61
|
+
match = Regexp.new("^#{Regexp.quote(path).gsub('/', '/+')}(.*)", nil, 'n')
|
62
|
+
host = Regexp.new("^#{Regexp.quote(host)}$", true, 'n') unless host.nil? || host.is_a?(Regexp)
|
63
|
+
|
64
|
+
@mapping << [host, path, match, app]
|
65
|
+
end
|
66
|
+
|
67
|
+
# The call handler setup to route a request given the mappings specified.
|
68
|
+
def call(env)
|
69
|
+
began_at = Time.now
|
70
|
+
path_info = env["PATH_INFO"].to_s
|
71
|
+
script_name = env['SCRIPT_NAME']
|
72
|
+
http_host = env['HTTP_HOST']
|
73
|
+
last_result = nil
|
74
|
+
|
75
|
+
@mapping.each do |host, path, match, app|
|
76
|
+
next unless host.nil? || http_host =~ host
|
77
|
+
next unless path_info =~ match && rest = $1
|
78
|
+
next unless rest.empty? || rest[0] == ?/
|
79
|
+
|
80
|
+
rest = "/" if rest.empty?
|
81
|
+
|
82
|
+
env['SCRIPT_NAME'] = script_name + path
|
83
|
+
env['PATH_INFO'] = rest
|
84
|
+
last_result = app.call(env)
|
85
|
+
|
86
|
+
cascade_setting = app.respond_to?(:cascade) ? app.cascade : true
|
87
|
+
cascade_statuses = cascade_setting.respond_to?(:include?) ? cascade_setting : Mounter::DEFAULT_CASCADE
|
88
|
+
break unless cascade_setting && cascade_statuses.include?(last_result[0])
|
89
|
+
end
|
90
|
+
last_result || begin
|
91
|
+
env['SCRIPT_NAME'] = script_name
|
92
|
+
env['PATH_INFO'] = path_info
|
93
|
+
Tennpipes::Logger::Rack.new(nil,'/').send(:log, env, 404, {}, began_at) if logger.debug?
|
94
|
+
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
##
|
3
|
+
# Runs the Tennpipes apps as a self-hosted server using:
|
4
|
+
# thin, mongrel, or WEBrick in that order.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# Tennpipes.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found
|
8
|
+
# Tennpipes.run!("0.0.0.0", "4000", "mongrel") # use => host: "0.0.0.0", port: "4000", adapter: "mongrel"
|
9
|
+
#
|
10
|
+
def self.run!(options={})
|
11
|
+
Tennpipes.load!
|
12
|
+
Server.start(*detect_application(options))
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
def self.detect_application(options)
|
20
|
+
default_config_file = 'config.ru'
|
21
|
+
if (config_file = options.delete(:config)) || File.file?(default_config_file)
|
22
|
+
config_file ||= default_config_file
|
23
|
+
fail "Rack config file `#{config_file}` must have `.ru` extension" unless config_file =~ /\.ru$/
|
24
|
+
rack_app, rack_options = Rack::Builder.parse_file(config_file)
|
25
|
+
[rack_app, rack_options.merge(options)]
|
26
|
+
else
|
27
|
+
[Tennpipes.application, options]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# This module builds a Tennpipes server to run the project based on available handlers.
|
33
|
+
#
|
34
|
+
class Server < Rack::Server
|
35
|
+
DEFAULT_ADDRESS = { :Host => '127.0.0.1', :Port => 3000 }
|
36
|
+
|
37
|
+
# Server Handlers
|
38
|
+
Handlers = [:thin, :puma, :'spider-gazelle', :mongrel, :trinidad, :webrick]
|
39
|
+
|
40
|
+
# Starts the application on the available server with specified options.
|
41
|
+
def self.start(app, options={})
|
42
|
+
options = options.to_hash.symbolize_keys
|
43
|
+
options.update(parse_server_options(options.delete(:options)))
|
44
|
+
options.update(detect_address(options))
|
45
|
+
options[:pid] = prepare_pid(options[:pid]) if options[:daemonize]
|
46
|
+
options[:server] = detect_rack_handler if options[:server].blank?
|
47
|
+
# disable Webrick AccessLog
|
48
|
+
options[:AccessLog] = []
|
49
|
+
new(options, app).start
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(options, app)
|
53
|
+
@options, @app = options, app
|
54
|
+
end
|
55
|
+
|
56
|
+
# Starts the application on the available server with specified options.
|
57
|
+
def start
|
58
|
+
puts "=> Tennpipes/#{Tennpipes.version} has taken the stage #{Tennpipes.env} at http://#{options[:Host]}:#{options[:Port]}"
|
59
|
+
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
60
|
+
super do |server|
|
61
|
+
server.threaded = true if server.respond_to?(:threaded=)
|
62
|
+
end
|
63
|
+
ensure
|
64
|
+
puts "<= Tennpipes leaves the gun, takes the cannoli" unless options[:daemonize]
|
65
|
+
end
|
66
|
+
|
67
|
+
# The application the server will run.
|
68
|
+
def app
|
69
|
+
@app
|
70
|
+
end
|
71
|
+
alias :wrapped_app :app
|
72
|
+
|
73
|
+
def options
|
74
|
+
@options
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Detects the supported handler to use.
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# detect_rack_handler => <ThinHandler>
|
83
|
+
#
|
84
|
+
def self.detect_rack_handler
|
85
|
+
Handlers.each do |handler|
|
86
|
+
begin
|
87
|
+
return handler if Rack::Handler.get(handler.to_s.downcase)
|
88
|
+
rescue LoadError
|
89
|
+
rescue NameError
|
90
|
+
end
|
91
|
+
end
|
92
|
+
fail "Server handler (#{Handlers.join(', ')}) not found."
|
93
|
+
end
|
94
|
+
|
95
|
+
# Prepares a directory for pid file.
|
96
|
+
#
|
97
|
+
def self.prepare_pid(pid)
|
98
|
+
pid = 'tmp/pids/server.pid' if pid.blank?
|
99
|
+
FileUtils.mkdir_p(File.dirname(pid))
|
100
|
+
File.expand_path(pid)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Parses an array of server options.
|
104
|
+
#
|
105
|
+
def self.parse_server_options(options)
|
106
|
+
parsed_server_options = Array(options).flat_map{ |option| option.split('=', 2) }
|
107
|
+
Hash[*parsed_server_options].symbolize_keys
|
108
|
+
end
|
109
|
+
|
110
|
+
# Detects Host and Port for Rack server.
|
111
|
+
#
|
112
|
+
def self.detect_address(options)
|
113
|
+
address = DEFAULT_ADDRESS.merge options.slice(:Host, :Port)
|
114
|
+
address[:Host] = options[:host] if options[:host].present?
|
115
|
+
address[:Port] = options[:port] if options[:port].present?
|
116
|
+
address
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
##
|
3
|
+
# This module it's used for bootstrap with tennpipes rake
|
4
|
+
# third party tasks, in your gem/plugin/extension you
|
5
|
+
# need only do this:
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# Tennpipes::Tasks.files << yourtask.rb
|
9
|
+
# Tennpipes::Tasks.files.concat(Dir["/path/to/all/my/tasks/*.rb"])
|
10
|
+
# Tennpipes::Tasks.files.unshift("yourtask.rb")
|
11
|
+
#
|
12
|
+
module Tasks
|
13
|
+
|
14
|
+
##
|
15
|
+
# Returns a list of files to handle with tennpipes rake
|
16
|
+
#
|
17
|
+
def self.files
|
18
|
+
@files ||= []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Manages current Tennpipes version for use in gem generation.
|
3
|
+
#
|
4
|
+
# We put this in a separate file so you can get tennpipes version
|
5
|
+
# without include full tennpipes core.
|
6
|
+
#
|
7
|
+
module Tennpipes
|
8
|
+
# The version constant for the current version of Tennpipes.
|
9
|
+
VERSION = '3.6.6' unless defined?(Tennpipes::VERSION)
|
10
|
+
|
11
|
+
#
|
12
|
+
# The current Tennpipes version.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
# The version number.
|
16
|
+
#
|
17
|
+
def self.version
|
18
|
+
VERSION
|
19
|
+
end
|
20
|
+
end # Tennpipes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Manages current Tennpipes version for use in gem generation.
|
3
|
+
#
|
4
|
+
# We put this in a separate file so you can get tennpipes version
|
5
|
+
# without include full tennpipes core.
|
6
|
+
#
|
7
|
+
module Tennpipes
|
8
|
+
# The version constant for the current version of Tennpipes.
|
9
|
+
VERSION = '0.0.2' unless defined?(Tennpipes::VERSION)
|
10
|
+
|
11
|
+
#
|
12
|
+
# The current Tennpipes version.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
# The version number.
|
16
|
+
#
|
17
|
+
def self.version
|
18
|
+
VERSION
|
19
|
+
end
|
20
|
+
end # Tennpipes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/app_gem/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Florian Gilcher"]
|
6
|
+
gem.email = ["florian.gilcher@asquera.de"]
|
7
|
+
gem.description = %q{TODO: Write a gem description}
|
8
|
+
gem.summary = %q{TODO: Write a gem summary}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "app_gem"
|
15
|
+
gem.require_paths = ["app", "lib"]
|
16
|
+
gem.version = AppGem::VERSION
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
|
2
|
+
|
3
|
+
module LibDemo
|
4
|
+
def self.give_me_a_random
|
5
|
+
@rand ||= rand(100)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Complex1Demo < Tennpipes::Application
|
10
|
+
set :reload, true
|
11
|
+
get("/old"){ "Old Sinatra Way" }
|
12
|
+
end
|
13
|
+
|
14
|
+
class Complex2Demo < Tennpipes::Application
|
15
|
+
set :reload, true
|
16
|
+
get("/old"){ "Old Sinatra Way" }
|
17
|
+
|
18
|
+
controllers :var do
|
19
|
+
get(:destroy){ params.inspect }
|
20
|
+
end
|
21
|
+
|
22
|
+
get("/"){ "The magick number is: 12!" } # Change only the number!!!
|
23
|
+
end
|
24
|
+
|
25
|
+
Complex1Demo.controllers do
|
26
|
+
get("/"){ "Given random #{LibDemo.give_me_a_random}" }
|
27
|
+
end
|
28
|
+
|
29
|
+
Complex2Demo.controllers do
|
30
|
+
end
|
31
|
+
|
32
|
+
Tennpipes.load!
|