2020年10月1日木曜日

Sinatra で Rack::Lint の挙動を確認してみる

概要

Sinatra では Rack::Lint がデフォルトで使われています
今回はどのような感じで Rack::Lint が使われているか確認してみました

環境

  • macOS 10.15.6
  • Ruby 2.7.1p83
    • sinatra 2.0.7

そもそも Rack::Lint とは

レスポンスを返却する際に正しい形式でレスポンスが作成されているかチェックしてくれるミドルウェアです
例えばステータスコードがおかしな数字になっている場合などに自動でチェックしてくれます

config.ru

require './app'
run MyApp

status コードは 100 以上でないといけない

一番簡単に Rack::Lint のエラーを起動するのはステータスコードかなと思います
例えばステータスコードを 1 のように存在してはいけないコードを返そうとするとエラーが発生します

require 'sinatra/base'

class MyApp < Sinatra::Base
  get '/test' do
    status 1
  end
end

Rack::Lint::LintError at /test Status must be >=100 seen as integer」こんな感じのエラーが表示されると思います

ステータスコードが 204 のときには Content-Type と Content-Length を自動で削除する

Sinatra は Rack::Lintcheck_content_typecheck_content_length にひっかからないようにステータスコードを 204 or 304 で返却する場合には自動で削除してくれています

参考: https://www.rubydoc.info/gems/rack/Rack/Lint#check_content_type-instance_method

例えば以下のようなコードを書いてみましょう

require 'sinatra/base'

class MyApp < Sinatra::Base
  get '/test' do
    headers 'Content-Type' => 'text/xml'
    status 204
    body 'ok'
  end
end

これを起動するとわかりますが Content-TypeContent-Length がレスポンスヘッダに含まれていないことが確認できると思います

  • curl -v localhost:9292/test
< HTTP/1.1 204 No Content
< X-Content-Type-Options: nosniff
< Connection: close
< Server: thin

check_env は行っていない?

Rack::Lint には check_env というメソッドがありますがこれを内部で使っている感じはありませんでした
もし自分でチェックで使う場合には以下のように使えます

  • vim config.ru
require './app'

app = MyApp.new
env = nil
Rack::Lint.new(app).check_env(env)

run app

アプリを起動しようとすると「Rack::Lint::LintError: env nil is not a Hash, but NilClass」でエラーになるのが確認できると思います
自分でミドルウェアを作成してそこでチェックしても OK かなと思います

最後に

Sinatra 内での Rack::Lint 挙動について確認してみました
デフォルトで使えるようになっていますが Sinatra 内部で Rack::Lint の機能を使っている部分は少ないようです
Rack::Lint にはいくつかのチェック用のメソッドがあるのでそれらを使って自分でミドルウェアを作成してチェックするのを想定している感じかなと思います

0 件のコメント:

コメントを投稿