1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
| | # -*- encoding: binary -*-
# Copyright (C) 2013-2016 all contributors <yahns-public@yhbt.net>
# License: GPL-3.0+ (https://www.gnu.org/licenses/gpl-3.0.txt)
# frozen_string_literal: true
require 'rack'
class Yahns::Rack # :nodoc:
attr_reader :preload
# enforce a single instance for the identical config.ru
def self.instance_key(*args)
ru = args[0]
# it's safe to expand_path now since we enforce working_directory in the
# top-level config is called before any apps are created
# ru may also be a Rack::Builder object or any already-built Rack app
ru.respond_to?(:call) ? ru.object_id : File.expand_path(ru)
end
def initialize(ru, opts = {})
# always called after config file parsing, may be called after forking
@app = lambda do
if ru.respond_to?(:call)
inner_app = ru.respond_to?(:to_app) ? ru.to_app : ru
else
inner_app = case ru
when /\.ru$/
raw = File.read(ru)
raw.sub!(/^__END__\n.*/, '')
eval("Rack::Builder.new {(\n#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
else
require ru
Object.const_get(File.basename(ru, '.rb').capitalize)
end
end
inner_app
end
@ru = ru
@preload = opts[:preload]
build_app! if @preload
end
def config_context
ctx_class = Class.new(Yahns::HttpClient)
ctx_class.extend(Yahns::HttpContext)
ctx_class.http_ctx_init(self)
ctx_class
end
def build_app!
if @app.respond_to?(:arity) && @app.arity == 0
Gem.refresh if defined?(Gem) && Gem.respond_to?(:refresh)
@app = @app.call
end
end
# allow different HttpContext instances to have different Rack defaults
def app_defaults
{
# logger is set in http_context
"rack.errors" => $stderr,
"rack.multiprocess" => true,
"rack.multithread" => true,
"rack.run_once" => false,
"rack.hijack?" => true,
"rack.version" => [ 1, 2 ],
"SCRIPT_NAME" => ''.dup,
# this is not in the Rack spec, but some apps may rely on it
"SERVER_SOFTWARE" => 'yahns'.dup
}
end
def app_after_fork
build_app! unless @preload
@app
end
end
# register ourselves
Yahns::Config::APP_CLASS[:rack] = Yahns::Rack
|