Class: Puma::Rack::Builder
- Inherits:
-
Object
- Object
- Puma::Rack::Builder
- Defined in:
- lib/puma/rack/builder.rb
Overview
Rack::Builder implements a small DSL to iteratively construct Rack applications.
Example:
require 'rack/lobster'
app = Rack::Builder.new do
use Rack::CommonLogger
use Rack::ShowExceptions
map "/lobster" do
use Rack::Lint
run Rack::Lobster.new
end
end
run app
Or
app = Rack::Builder.app do
use Rack::CommonLogger
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
run app
use adds middleware to the stack, run dispatches to an application. You can use map to construct a Rack::URLMap in a convenient way.
Class Method Summary collapse
- .app(default_app = nil, &block) ⇒ Object
- .new_from_string(builder_script, file = "(rackup)") ⇒ Object
- .parse_file(config, opts = Options.new) ⇒ Object
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(default_app = nil, &block) ⇒ Builder
constructor
A new instance of Builder.
-
#map(path, &block) ⇒ Object
Creates a route within the application.
-
#run(app) ⇒ Object
Takes an argument that is an object that responds to #call and returns a Rack response.
- #to_app ⇒ Object
-
#use(middleware, *args, &block) ⇒ Object
Specifies middleware to use in a stack.
-
#warmup(prc = nil, &block) ⇒ Object
Takes a lambda or block that is used to warm-up the application.
Constructor Details
#initialize(default_app = nil, &block) ⇒ Builder
Returns a new instance of Builder.
180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/puma/rack/builder.rb', line 180 def initialize(default_app = nil,&block) @use, @map, @run, @warmup = [], nil, default_app, nil # Conditionally load rack now, so that any rack middlewares, # etc are available. begin require 'rack' rescue LoadError end instance_eval(&block) if block_given? end |
Class Method Details
.app(default_app = nil, &block) ⇒ Object
193 194 195 |
# File 'lib/puma/rack/builder.rb', line 193 def self.app(default_app = nil, &block) self.new(default_app, &block).to_app end |
.new_from_string(builder_script, file = "(rackup)") ⇒ Object
175 176 177 178 |
# File 'lib/puma/rack/builder.rb', line 175 def self.new_from_string(builder_script, file="(rackup)") eval "Puma::Rack::Builder.new {\n" + builder_script + "\n}.to_app", TOPLEVEL_BINDING, file, 0 end |
.parse_file(config, opts = Options.new) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/puma/rack/builder.rb', line 159 def self.parse_file(config, opts = Options.new) = {} if config =~ /\.ru$/ cfgfile = ::File.read(config) if cfgfile[/^#\\(.*)/] && opts = opts.parse! $1.split(/\s+/) end cfgfile.sub!(/^__END__\n.*\Z/m, '') app = new_from_string cfgfile, config else require config app = Object.const_get(::File.basename(config, '.rb').capitalize) end return app, end |
Instance Method Details
#call(env) ⇒ Object
287 288 289 |
# File 'lib/puma/rack/builder.rb', line 287 def call(env) to_app.call(env) end |
#map(path, &block) ⇒ Object
Creates a route within the application.
Rack::Builder.app do
map '/' do
run Heartbeat
end
end
The use method can also be used here to specify middleware to run under a specific path:
Rack::Builder.app do
map '/' do
use Middleware
run Heartbeat
end
end
This example includes a piece of middleware which will run before requests hit Heartbeat.
274 275 276 277 |
# File 'lib/puma/rack/builder.rb', line 274 def map(path, &block) @map ||= {} @map[path] = block end |
#run(app) ⇒ Object
Takes an argument that is an object that responds to #call and returns a Rack response. The simplest form of this is a lambda object:
run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
However this could also be a class:
class Heartbeat
def self.call(env)
[200, { "Content-Type" => "text/plain" }, ["OK"]]
end
end
run Heartbeat
238 239 240 |
# File 'lib/puma/rack/builder.rb', line 238 def run(app) @run = app end |
#to_app ⇒ Object
279 280 281 282 283 284 285 |
# File 'lib/puma/rack/builder.rb', line 279 def to_app app = @map ? generate_map(@run, @map) : @run fail "missing run or map statement" unless app app = @use.reverse.inject(app) { |a,e| e[a] } @warmup.call(app) if @warmup app end |
#use(middleware, *args, &block) ⇒ Object
Specifies middleware to use in a stack.
class Middleware
def initialize(app)
@app = app
end
def call(env)
env["rack.some_header"] = "setting an example"
@app.call(env)
end
end
use Middleware
run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
All requests through to this application will first be processed by the middleware class. The call method in this example sets an additional environment key which then can be referenced in the application if required.
216 217 218 219 220 221 222 |
# File 'lib/puma/rack/builder.rb', line 216 def use(middleware, *args, &block) if @map mapping, @map = @map, nil @use << proc { |app| generate_map app, mapping } end @use << proc { |app| middleware.new(app, *args, &block) } end |
#warmup(prc = nil, &block) ⇒ Object
Takes a lambda or block that is used to warm-up the application.
warmup do |app|
client = Rack::MockRequest.new(app)
client.get('/')
end
use SomeMiddleware
run MyApp
251 252 253 |
# File 'lib/puma/rack/builder.rb', line 251 def warmup(prc=nil, &block) @warmup = prc || block end |