Class: Rackup::Handler::WEBrick

Inherits:
WEBrick::HTTPServlet::AbstractServlet
  • Object
show all
Includes:
Rack
Defined in:
lib/rackup/handler/webrick.rb

Constant Summary

Constants included from Rack

Rack::Handler, Rack::Server

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, app) ⇒ WEBrick

Returns a new instance of WEBrick.



67
68
69
70
# File 'lib/rackup/handler/webrick.rb', line 67

def initialize(server, app)
  super server
  @app = app
end

Class Method Details

.run(app, **options) {|@server| ... } ⇒ Object

Yields:

  • (@server)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rackup/handler/webrick.rb', line 32

def self.run(app, **options)
  environment  = ENV['RACK_ENV'] || 'development'
  default_host = environment == 'development' ? 'localhost' : nil

  if !options[:BindAddress] || options[:Host]
    options[:BindAddress] = options.delete(:Host) || default_host
  end
  options[:Port] ||= 8080
  if options[:SSLEnable]
    require 'webrick/https'
  end

  @server = ::WEBrick::HTTPServer.new(options)
  @server.mount "/", Rackup::Handler::WEBrick, app
  yield @server if block_given?
  @server.start
end

.shutdownObject



60
61
62
63
64
65
# File 'lib/rackup/handler/webrick.rb', line 60

def self.shutdown
  if @server
    @server.shutdown
    @server = nil
  end
end

.valid_optionsObject



50
51
52
53
54
55
56
57
58
# File 'lib/rackup/handler/webrick.rb', line 50

def self.valid_options
  environment  = ENV['RACK_ENV'] || 'development'
  default_host = environment == 'development' ? 'localhost' : '0.0.0.0'

  {
    "Host=HOST" => "Hostname to listen on (default: #{default_host})",
    "Port=PORT" => "Port to listen on (default: 8080)",
  }
end

Instance Method Details

#service(req, res) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rackup/handler/webrick.rb', line 72

def service(req, res)
  res.rack = true
  env = req.meta_vars
  env.delete_if { |k, v| v.nil? }

  rack_input = StringIO.new(req.body.to_s)
  rack_input.set_encoding(Encoding::BINARY)

  env.update(
    RACK_INPUT        => rack_input,
    RACK_ERRORS       => $stderr,
    RACK_URL_SCHEME   => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http",
    RACK_IS_HIJACK    => true,
  )

  env[QUERY_STRING] ||= ""
  unless env[PATH_INFO] == ""
    path, n = req.request_uri.path, env[SCRIPT_NAME].length
    env[PATH_INFO] = path[n, path.length - n]
  end
  env[REQUEST_PATH] ||= [env[SCRIPT_NAME], env[PATH_INFO]].join

  status, headers, body = @app.call(env)
  begin
    res.status = status

    if value = headers[RACK_HIJACK]
      io_lambda = value
    elsif !body.respond_to?(:to_path) && !body.respond_to?(:each)
      io_lambda = body
    end

    if value = headers.delete('set-cookie')
      res.cookies.concat(Array(value))
    end

    headers.each { |key, value|
      # Skip keys starting with rack., per Rack SPEC
      next if key.start_with?('rack.')

      # Since WEBrick won't accept repeated headers,
      # merge the values per RFC 1945 section 4.2.
      value = value.join(", ") if Array === value
      res[key] = value
    }

    if io_lambda
      rd, wr = IO.pipe
      res.body = rd
      res.chunked = true
      io_lambda.call wr
    elsif body.respond_to?(:to_path)
      res.body = ::File.open(body.to_path, 'rb')
    else
      body.each { |part|
        res.body << part
      }
    end
  ensure
    body.close if body.respond_to? :close
  end
end