Ruby

【Ruby】WEBrickで簡単なHTTPサーバーを作って動かしてみよう!

※当サイトではアフィリエイトプログラムを利用して商品を紹介しています。

コード

ひでまる
ひでまる
こんにちは!ひでまるです!
今回はRubyのWEBrickを使ってHTTPサーバを構築していくよ!

 

こんな方におすすめ

  • Rubyを学習している人
  • WEBrick使ってみたい人

現場でRubyを使って開発しているので、個人の勉強記録として残します。

 

普段はRailsで開発を行っているのですが、リクエスト周りはよしなにRailsがやってくれるので、勉強としてRubyだけでリクエスト周りを作っていきたいと思います。

 

要件定義

  • http://127.0.0.1:20080/welcomeとリクエストしたら、「ようこそ!ゲストさん」というページがブラウザで表示される
  • http://127.0.0.1:20080/welcome?name=佐藤とリクエストしたら、「ようこそ!佐藤さん」というページがブラウザで表示される
  • Railsのようなフレームワークは使わない
  • ライブラリはWEBrickを使う

環境

Ruby 2.6.10

 

WEBrickとは?

一言で言うと、Rubyで簡単にHTTPサーバを立ち上げられるライブラリです。

Ruby 3.4 リファレンスマニュアル(WEBrick)

 

WEBrickの特徴

  1. 簡単にHTTPサーバーを構築できる
    • 数行のRubyコードで、HTTPサーバを起動することができます。
  2. Rubyの標準ライブラリ(※Ruby 3.0以降は別途インストールが必要
    • Ruby 2 までは標準ライブラリとして組み込まれていたのですが、Ruby 3.0 以降では gem install webrick でインストールが必要になります。
  3. 柔軟なカスタマイズが可能
    • リクエストごとに動的なレスポンスを返すAPIサーバーとしての利用もできます。
  4. サーブレットによる処理の管理
    • サーブレットという仕組みで、URLごとに異なる処理を割り当てることができます。

サーブレットとは?

一言で言うと、リクエストを処理して、レスポンスを作成するプログラムの部品です。

「このリクエストにはこの処理を使う」と言った感じに、サーブレットを使えば、URLごとに違う処理をしたり、動的にメッセージを変えたりできます。
例えば、「/hello というURLにアクセスされたら「こんにちは!」と返し、
「/goodbye にアクセスされたら「さようなら!」と返すように、URLごとに異なる処理を実行できます。
サーブレットはWEBrick::HTTPServlet::AbstractServlet を使って、自分だけのサーブレットを作成できます。
Ruby 3.4 リファレンスマニュアル(WEBrick::HTTPServlet::AbstractServlet)

◎サンプルコード

require 'webrick'

# ここでサーブレットを定義
class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
 def do_GET(req, res)
  res.status = 200
  res['Content-Type'] = 'text/html'
  res.body = "こんにちは!これはWEBrickのサーブレットからのメッセージです。"
 end
end

server = WEBrick::HTTPServer.new(:Port => 3000)

server.mount '/hello', HelloServlet

trap('INT') { server.shutdown }
server.start

サーブレットの流れ

  1. リクエストの受信
    WEBrickサーバーがクライアントからのHTTPリクエストを受け取ります。
  2. サーブレットのマッピング
    リクエストされたパス(URL)に対応するサーブレットが特定されます。server.mount '/hello', HelloServlet でパスとサーブレットの関連付けを行います。
  3. 対応するメソッドを決める
    リクエストのHTTPメソッドに応じて、サーブレット内の対応するメソッド(例:do_GET, do_POST)が呼び出されます。
  4. レスポンスの生成
    サーブレットはリクエストオブジェクトから必要なデータを取得し、レスポンスオブジェクトに適切なステータスコード、ヘッダー、ボディを設定してクライアントに返します。

WEBrickを使ってHTTPサーバーを構築してみる

◎ファイル構成
your_project_directory
├── server.rb # 上記のRubyサーバースクリプト
└── welcome.html # HTMLテンプレートファイル

※ 今回はサーブレットを使わず、手軽にリクエストを処理するために mount_proc を使用します。
mount_proc を使うことで、簡単な処理をブロック(do...end)内に直接記述することができます。
Ruby 3.4 リファレンスマニュアル(mount_proc)

step
1
require 'webrick' でWEBrickを読み込む

最初に、Rubyの標準ライブラリであるWEBrickを読み込みます。
(※Ruby 3.0以降の場合は gem install webrick でインストールが必要になります)

require webrick

 

step
2
WEBrick::HTTPServer.new でサーバーを作成する

サーバーの設定も行います。

srv = WEBrick::HTTPServer.new({
  :DocumentRoot => './',         # 現在のディレクトリをルートに設定
  :BindAddress  => '127.0.0.1',   # ローカルホストでバインド
  :Port         => 20080         # ポート20080でサーバーを起動
})

 

step
3
mount_proc/welcome へのリクエストを受け付ける

/welcome にアクセスされたときに、クエリパラメータに応じてHTMLを動的に生成する処理を設定します。

srv.mount_proc('/welcome') do |req, res|

  # クエリパラメータ 'name' を取得し、UTF-8に強制変換
  name = req.query['name'] ? req.query['name'].force_encoding('UTF-8') : 'ゲスト'

  # welcome.html の内容をUTF-8で読み込む
  html_content = File.read('welcome.html', encoding: 'UTF-8')

  # {{name}} プレースホルダーをクエリパラメータの値で置き換える
  updated_content = html_content.gsub('{{name}}', name)

  # レスポンスとして更新されたHTMLを返す
  res['Content-Type'] = 'text/html; charset=UTF-8'
  res.body = updated_content
end

 

step
4
welcome.html のテンプレートファイルを作成する

同じディレクトリに welcome.html というファイルを作成し、welcome.htmlのbodyにようこそ!{{name}}さん!を記述します。

{{name}}の部分にクエリパラメータで送った名前が入ります。
・http://127.0.0.1:20080/welcome?name=佐藤でリクエストするとnameに佐藤が入る。

 

step
5
trap("INT") { srv.shutdown } でサーバーを安全に停止できるようにする

Ctrl + C でサーバーを停止した際に、安全にサーバーをシャットダウンする処理を追加します

trap("INT") { srv.shutdown }

 

step
6
srv.startでサーバーを起動する


最後にサーバーを起動して、リクエストの待ち受けを開始します。

srv.start

 

◎最終的なコード

require 'webrick'

srv = WEBrick::HTTPServer.new({
  :DocumentRoot => './',
  :BindAddress  => '127.0.0.1',
  :Port         => 20080
})

# /welcome のリクエスト受付
srv.mount_proc('/welcome') do |req, res|

  # クエリパラメータ 'name' を取得し、UTF-8に変換
  name = req.query['name'] ? req.query['name'].force_encoding('UTF-8') : 'ゲスト'

  # welcome.html の内容を読み込み
  html_content = File.read('welcome.html', encoding: 'UTF-8')

  # {{name}} プレースホルダーをクエリパラメータの値で置き換え
  updated_content = html_content.gsub('{{name}}', name)

  # レスポンスとして更新されたHTMLを返す
  res['Content-Type'] = 'text/html; charset=UTF-8'
  res.body = updated_content
end

trap("INT") { srv.shutdown }
srv.start

 

動作確認

  1. ターミナルで「ruby server.rb」を実行します。
  2. http://127.0.0.1:20080/welcome?name=佐藤でアクセスし画像のように出れば成功です!

終わりに

今回はWEBrickで簡易的なHTTPサーバについて学習してみました。
少しでも学習のお役に立てれば幸いです。

 

参考記事

Ruby 3.4 リファレンスマニュアル(WEBrick)

Ruby 3.4 リファレンスマニュアル(WEBrick::HTTPServlet::AbstractServlet)

 

おすすめ書籍

書籍:プロを目指す人のためのRuby入門
とても分かりやすい本なので、Ruby学習にはおすすめの一冊です!

-Ruby