2015-08-18 22:45 GMT+08:00 Yichun Zhang (agentzh) <age...@gmail.com>:
> 2015-08-18 22:17 GMT+08:00 Zoom.Quiet:
>> # 背景
>> 历史遗留客户端, 只接受特定大小写的 HTTP 响应 HEAD 字段
>>
>> - 比如 FooBar: 1234567
>> - 但是, 后来使用标准化库后,自动将字段名修订为 Foobar 类似字串
>> - 客户端就无法接受了
>
> 一般地,可以用 ngx.header API 来做。为安全起见,先清空响应头,再生成响应头。例如:
>
> local name = "FooBar"
> ngx.header[name] = nil -- ensure that the existing header names
> are erased completely
> ngx.header[name] = "1234567"
>
> 但须注意,在此之前不能有任何 ngx.say/ngx.print/ngx.send_headers/ngx.eof
> 这些操作。因为这些操作都会触发发送响应头。响应头发送出去了,就不能再修改响应头了。
>
>> - 同时,此时的 Nginx 是作为代理,将后端动态系统发布出来的,类似:
>> + proxy_pass http://myapi/;
>>
>
> 如果你使用 proxy_pass 的话,则你的 Lua 代码应该放在 header_filter_by_lua 中。
>
是也乎,( ̄▽ ̄)
今早,也重新挖掘了一下主模块,看到了这一对 filter
- header_filter_by_lua_file
- header_filter_by_lua
非常羞愧哪, 作为 OpenResty 早期拥趸,这么长时间以来,都没有建立起 ngx-style 的合法请求流程概念 ;-(
当前使用 header_filter_by_lua_file 加载 head_fixer.lua 已经解决问题 ;-)
local name = "FBar"
local h = ngx.resp.get_headers()
for k, v in pairs(h) do
if k =='fbar' then
ngx.log(ngx.ERR, k,'\t', v)
-- ensure that the existing header name erased completely
ngx.header[k] = nil
ngx.header[name] = v
end
end
另外,发现另外一个问题:
比如 ngx.header["date"]="blah" 可以把 Date 变成 date,
但 ngx.header["content-type"]="blah" 就不可以把 Content-Type 变成 content-type
这是否 遗留问题?
>> ngx.header["X-My-Header"] = 'blah blah'
>> local h = ngx.resp.get_headers()
>> for k, v in pairs(h) do
>> ngx.say(k,'\t', v)
>> if k ~='x-my-header' then
>> ngx.header["My-Header-X"] = 'blah blah'
>> end
>> end
>>
>
> 你这里在修改响应头前调用了 ngx.say(),从而导致响应头被自动发送。所以会抛出下面那个错误。
>
>>
>> 报错:
>> 2015/08/18 22:06:08 [error] 47371#0: *12 attempt to set
>> ngx.header.HEADER after sending out response headers, client:
>> 127.0.0.1, server: , request: "GET /echo HTTP/1.1", host:
>> "127.0.0.1:8081"
>>
>
>> 如果将测试脚本部署在代理路径上,类似:
>>
>> location / {
>> proxy_pass http://myapi/;
>> content_by_lua_file conf/lua/echo.lua;
>> }
>>
>
> 这是初学者常犯的错误了,一个 location 不能有两个 content handler. 你这里 proxy_pass 是一个
> content handler 而 content_by_lua 又是一个 content handler.
> 此二者会冲突,从而只有其中一个生效。正确的做法如我上面所说,使用 proxy_pass 时应结合使用
> header_filter_by_lua.
>
> Regards,
> -agentzh
--
Life's Pathetic, Let's Pythonic! 人生苦短, Python是岸!
俺: http://zoomquiet.io
授: http://creativecommons.org/licenses/by-sa/2.5/cn/
怒: 冗余不做,日子甭过!备份不做,十恶不赦!
KM keep growing environment culture which promoting organization be learnning!