ngx_mruby

ngx_mrubyの裏(不人気)機能(2)

今日のngx_mrubyの裏(不人気)機能を紹介したいと思います。

ngx_mrubyにRubyのクラスや新しいメソッドを追加したい場合に、直接コードを書いたものをmruby_initに渡したり、mrbgemとして切り出して書いているだろうと思います。

ただ、ngx_mrubyに依存したメソッドをシュッと追加しつつも、nginx起動時ではなくてnginxビルド時にリンクさせておきたい場合もあるでしょう。その時に改めてmrbgemを作るのも面倒な時があると思います。

実はngx_mrubyの裏(不人気)機能として、リポジトリのngx_mruby/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rbというファイルがあり、その中にRubyのクラスやメソッドを直接追加することで、nginxビルド時にリンクしてくれます。今だとこんな便利メソッドが書かれていますね。

class Nginx
  class Request
    def scheme
      self.var.scheme
    end

    def document_root
      Nginx::Server.new.document_root
    end

    def body
      self.read_body
      self.get_body
    end

    def uri_args
      args_to_hash(self.args)
    end

    def uri_args=(params)
      raise ArgumentError unless params.is_a?(Hash)
      self.args = params.map{|k,v| "#{k}=#{v}"}.join("&")
    end

    def post_args
      args_to_hash(self.body)
    end

    private

    def args_to_hash(args)
      Hash[*args.split("&").map{|arg| arg.split("=")}.flatten]
    end
  end

  class Headers_in
    def user_agent
      self["User-Agent"]
    end
  end

  def self.var
    Var.new
  end
end

module Kernel
  def get_server_class
    Nginx
  end
end

実は、ngx_mrubyのrack-base-apiもngx_mruby/mrbgems/以下に定義されていたりします。

ということで、nginxビルド時にmrubyにこういったクラスやメソッドをリンクしておきたい、かつ、mrbgemに切り出すには汎用性にかけるような実装は、ここにシュッと書いてしまうのも良いかもしれません。