それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

nginx luaでリクエストのURL(PATH)を取得して、特定リクエストPATHのときだけレスポンスを書き換えたい。

nginx lua

リクエストのURLを取得する

lua 側で特にすることはない。nginx側にある変数を参照する

local url = ngx.var.scseheme .. ngx.var.server_name .. ngx.var.uri
local u = string.format("%s://%s%s", ngx.var.scheme, ngx.var.server_name,ngx.var.uri )

nginx側にある変数は、任意のモノも定義できるし、rewrite で マッチしたものもある。

基本的に用意されている変数は、一覧から拾えばいい

nginx の $1 / $2 / $3 にアクセスする

nginx のvar を使って、ロケーションを見ることもできると思う。

ngx.var[1] -- nginx location $1 
ngx.var[2] -- nginx location $2 
ngx.var[3] -- nginx location $3 

または、いったん変数に格納する

set $my_name $1

xxx_by_lua_block{
  ngx.var.my_name
}

コレを使えば、nginxの変数に格納して、lua から参照すれば簡単だ。

body_filter で、</head>を書き換える

body_filter はBodyがChunkで転送されてくる前提なので、Body全体を置換できない。

わかりやすく言うと、数行単位で、body_filterがCallされる。

そのため、いったん変数にためておいて、まとめて出力する

body_filter_by_lua_block {
  local chunk, eof = ngx.arg[1], ngx.arg[2]
  if not(eof) then
    ngx.ctx.body = (ngx.ctx.body or "") .. chunk
    ngx.arg[1] = ''
  else
    local body = ngx.ctx.body
    ngx.arg[1]= body
  end
}

ちょっとわかりにくいかもしれない

また、nginx 本体の subfilterの後で実行される。

internalなリクエストで処理をする

nginx の基本設定でも内部へサブリクエストを送信できる。同じことをluaから呼び出す。

ngx.exec( url )

lua から呼び出すことで、認証の確認などを/auth などの特定URLに丸投げできて便利。

また、nginx側の処理とlua皮の処理を分けるために、あえてexecするのもあり

location /a {
    content_by_lua { ngx.exec('@a') }
}
location @a {
    proxy_pass xxxx
}

こうすれば、コンテンツの書き換えが楽になる。