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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/tina4/webserver.rb', line 13
def start
Tina4.print_banner
Tina4::Debug.info("Starting Tina4 WEBrick server on http://#{@host}:#{@port}")
@server = WEBrick::HTTPServer.new(
BindAddress: @host,
Port: @port,
Logger: WEBrick::Log.new(File::NULL),
AccessLog: []
)
rack_app = @app
servlet = Class.new(WEBrick::HTTPServlet::AbstractServlet) do
define_method(:initialize) do |server, app|
super(server)
@app = app
end
%w[GET POST PUT DELETE PATCH HEAD OPTIONS].each do |http_method|
define_method("do_#{http_method}") do |webrick_req, webrick_res|
handle_request(webrick_req, webrick_res)
end
end
define_method(:handle_request) do |webrick_req, webrick_res|
env = build_rack_env(webrick_req)
status, , body = @app.call(env)
webrick_res.status = status
.each do |key, value|
if key.downcase == "set-cookie"
Array(value.split("\n")).each { |c| webrick_res.cookies << WEBrick::Cookie.parse_set_cookie(c) }
else
webrick_res[key] = value
end
end
response_body = ""
body.each { |chunk| response_body += chunk }
webrick_res.body = response_body
end
define_method(:build_rack_env) do |req|
input = StringIO.new(req.body || "")
env = {
"REQUEST_METHOD" => req.request_method,
"PATH_INFO" => req.path,
"QUERY_STRING" => req.query_string || "",
"SERVER_NAME" => webrick_req_host,
"SERVER_PORT" => webrick_req_port,
"CONTENT_TYPE" => req.content_type || "",
"CONTENT_LENGTH" => (req.content_length rescue 0).to_s,
"REMOTE_ADDR" => req.peeraddr&.last || "127.0.0.1",
"rack.input" => input,
"rack.errors" => $stderr,
"rack.url_scheme" => "http",
"rack.version" => [1, 3],
"rack.multithread" => true,
"rack.multiprocess" => false,
"rack.run_once" => false
}
req..each do |key, values|
env_key = "HTTP_#{key.upcase.gsub('-', '_')}"
env[env_key] = values.join(", ")
end
env
end
end
host = @host
port = @port.to_s
servlet.define_method(:webrick_req_host) { host }
servlet.define_method(:webrick_req_port) { port }
@server.mount("/", servlet, rack_app)
trap("INT") { @server.shutdown }
trap("TERM") { @server.shutdown }
@server.start
end
|