読者です 読者をやめる 読者になる 読者になる

【Rails】WEBrickについて

RackでWebサーバーたてた。
よくわからないから、コードを追っていたら前からわからなかったWEBrickについてなんかわかったような。
めも

まずはコード張っとく。

require 'webrick'
require 'erb'

document_root = '/var/www/html/rails/rubyApp/app/'

server = WEBrick::HTTPServer.new({
  :DocumentRoot => document_root,
  :BindAddress => '0.0.0.0',
  :Port => 10080
})


server.mount_proc("/") { |req, res|

  path = File.join(document_root,*req.path.split("/"))
  path += ".utf-8" if /\.html\.[a-z][a-z]$/ =~ path 

  File.open(path){|file|
  	res.body = (ERB.new(File.read(path)).result(binding))
  }
  
  # 拡張子とContent-Typeの対応表
  content_types = {
    ".html" => "text/html", ".txt" => "text/plain",
    ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg",
    ".gif" => "image/gif", ".png" => "image/png", 
    ".mp3" => "audio/mpeg", ".mid"   => "audio/midi", 
    ".css"   => "text/css", ".xhtml" => "application/xhtml+html",
    ".svg"   => "image/svg+xml"  
        
  }
  
  # filenameの拡張子を見てContent-Typeを設定
    content_type = content_types[File.extname(path)]
    
     #Content-Typeが見つからなかったらtext/htmlを設定
    if content_type==nil
      content_type = "text/html"
    end
         
    res["Content-Type"] = content_type
 }

['INT', 'TERM'].each {|signal|
  Signal.trap(signal){ server.shutdown }
}

server.start
<||


まず
werbrickとerb(テンプレートエンジン読み込む)

>|ruby|
require 'webrick'
require 'erb'

WEBrick::HTTPServer.newしてあげる。
/.rbenv/versions/2.1.0/lib/ruby/2.1.0/webrick.rb
のinitialize method で初期化される。

document_root = '/var/www/html/rails/rubyApp/app/'

server = WEBrick::HTTPServer.new({
  :DocumentRoot => document_root,
  :BindAddress => '0.0.0.0',
  :Port => 10080
})


webrickのinitialize method確認
/.rbenv/versions/2.1.0/lib/ruby/2.1.0/webrick.rb

def initialize(config={}, default=Config::HTTP)
      super(config, default)
      @http_version = HTTPVersion::convert(@config[:HTTPVersion])

      @mount_tab = MountTable.new
      if @config[:DocumentRoot]
        mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
              @config[:DocumentRootOptions])
      end

      unless @config[:AccessLog]
        @config[:AccessLog] = [
          [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
          [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
        ]
      end

      @virtual_hosts = Array.new
end

いっぱいnewしてる。
ここで書くときりがないので、

super(config, default)

コレより前に

require 'webrick/server'

書いてあるのと

class HTTPServer < ::WEBrick::GenericServer
<||

::WEBrick::GenericServer継承してるから
中身確認
.rbenv/versions/2.1.0/lib/ruby/2.1.0/webrick/server.rb

>|ruby|
def initialize(config={}, default=Config::General)
      @config = default.dup.update(config)
      @status = :Stop
      @config[:Logger] ||= Log::new
      @logger = @config[:Logger]

      @tokens = SizedQueue.new(@config[:MaxClients])
      @config[:MaxClients].times{ @tokens.push(nil) }

      webrickv = WEBrick::VERSION
      rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
      @logger.info("WEBrick #{webrickv}")
      @logger.info("ruby #{rubyv}")

      @listeners = []
      unless @config[:DoNotListen]
        if @config[:Listen]
          warn(":Listen option is deprecated; use GenericServer#listen")
        end
        listen(@config[:BindAddress], @config[:Port])
        if @config[:Port] == 0
          @config[:Port] = @listeners[0].addr[1]
        end
      end
end

またいろいろ書いてる。。。
まぁログの設定とかか。
listen methodだけみとこ。多分ソケット作ってる。

def listen(address, port)
    @listeners += Utils::create_listeners(address, port, @logger)
end

また違うファイルから読んでるー。。
一応確認

.rbenv/versions/2.1.0/lib/ruby/2.1.0/webrick/utils.rb

>|ruby|
##
# Creates TCP server sockets bound to +address+:+port+ and returns them.
#
# It will create IPV4 and IPV6 sockets on all interfaces.


def create_listeners(address, port, logger=nil)
unless port
raise ArgumentError, "must specify port"
end
sockets = Socket.tcp_server_sockets(address, port)
sockets = sockets.map {|s|
s.autoclose = false
TCPServer.for_fd(s.fileno)
}
return sockets
end
|