/
webrick.rb
85 lines (80 loc) · 2.68 KB
/
webrick.rb
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
81
82
83
84
85
require 'webrick'
require 'webmachine/version'
require 'webmachine/headers'
require 'webmachine/request'
require 'webmachine/response'
require 'webmachine/dispatcher'
module Webmachine
module Adapters
# Connects Webmachine to WEBrick.
module WEBrick
# Starts the WEBrick adapter
def self.run
c = Webmachine.configuration
options = {
:Port => c.port,
:BindAddress => c.ip
}.merge(c.adapter_options)
server = Webmachine::Adapters::WEBrick::Server.new options
trap("INT"){ server.shutdown }
Thread.new { server.start }.join
end
# WEBRick::HTTPServer that is run by the WEBrick adapter.
class Server < ::WEBrick::HTTPServer
# Handles a request
def service(wreq, wres)
header = Webmachine::Headers.new
wreq.each {|k,v| header[k] = v }
request = Webmachine::Request.new(wreq.request_method,
wreq.request_uri,
header,
RequestBody.new(wreq))
response = Webmachine::Response.new
Webmachine::Dispatcher.dispatch(request, response)
wres.status = response.code.to_i
response.headers.each do |k,v|
wres[k] = v
end
wres['Server'] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(" ")
case response.body
when String
wres.body << response.body
when Enumerable
wres.chunked = true
response.body.each {|part| wres.body << part }
else
if response.body.respond_to?(:call)
wres.chunked = true
wres.body << response.body.call
end
end
end
end
# Wraps the WEBrick request body so that it can be passed to
# {Request} while still lazily evaluating the body.
class RequestBody
def initialize(request)
@request = request
end
# Converts the body to a String so you can work with the entire
# thing.
def to_s
@value ? @value.join : @request.body
end
# Iterates over the body in chunks. If the body has previously
# been read, this method can be called again and get the same
# sequence of chunks.
# @yield [chunk]
# @yieldparam [String] chunk a chunk of the request body
def each
if @value
@value.each {|chunk| yield chunk }
else
@value = []
@request.body {|chunk| @value << chunk; yield chunk }
end
end
end
end
end
end