nginx代理轉發因http_version導致lua讀取檔案不存在問題
本文由希希大隊長原創,原文連結:https://www.cnblogs.com/dongxixi/p/16267036.html
需求:
有一個POST介面,我希望在nginx上解析body體引數並直接返回一個對應的json文字檔案
實現:
因需求比較複雜,我選擇用lua指令碼實現body體解析並讀取對應檔案返回
nginx實現如下:
location /v1/list-panoramas {
access_by_lua_file /mnt/lua/list_pano.lua;
}
lua實現如下:
ngx.req.read_body(); local data = ngx.req.get_body_data(); local reqObj = ngx.req.get_post_args(); local storeId = reqObj["store_id"] -- 如果Content-Type是表單型別,則storeId有值 if storeId == nil then -- storeId無值表明Content-Type可能是application/json,需要從body體反序列化 jsonData = json.decode(nil, data) storeId = jsonData["store_id"] end -- 從靜態檔案目錄讀取, /mnt/static_file為nginx服務掛載的靜態目錄 local filePath = string.format("/mnt/static_file/%s", storeId) local fh, err = io.open(filePath, "r") if fh == nil then ngx.exit(404) else fileData = fh:read() io.close() ngx.header['Content-Type'] = 'application/json; charset=utf-8' ngx.say(fileData) end
問題描述:
當使用postman直接訪問該nginx時,可以獲取到對應json檔案內容
但因為需求需要,我需要從其他nginx代理轉發到該nginx,為方便理解,我們姑且命名該nginx為ng-A,代理轉發nginx為ng-B
ng-B的代理location如下:
location /v1/list-panoramas {
proxy_pass http://172.16.15.44;
}
當我向ng-B發起請求時(引數均為變,僅僅替換了請求host),卻意外得到了nginx返回的404結果
此時我檢查ng-A的error.log,發現請求已經到達ng-A,錯誤發生在lua指令碼open檔案時
2022/05/13 06:19:01 [error] 18#18: *2 open() "/etc/nginx/html/v1/list-panoramas" failed (2: No such file or directory), client: 10.100.39.1, server: 172.16.15.44, request: "POST /v1/list-panoramas HTTP/1.0", host: "172.16.15.44"
可以看出,這裡open的是 ‘/etc/nginx/html/v1/list-panoramas’
顯然與我上述lua指令碼中需要開啟的路徑不一致
lua中
local filePath = string.format("/mnt/static_file/%s", storeId)
這使我百思不得其解
問題排查與解決:
在一頓嘗試仍未解決以後,我在ng-A的日誌中發現,我直接請求ng-A成功得到預期結果時,log中列印的請求http version為HTTP/1.1,
但在我通過ng-B請求代理到ng-A時,ng-A列印的請求http version為HTTP/1.0,我隱隱感覺問題可能出在轉發時http version上,當
我在ng-B上加上 proxy_http_version 1.1; 後,再請求ng-B,順利拿到預期結果
location /v1/list-panoramas {
proxy_pass http://172.16.15.44;
proxy_http_version 1.1;
}
思考:
1、為什麼在ng代理轉發後http version變成了1.0呢?
在查閱相關資料後得知,代理轉發過程中,http version nginx會有一個預設值,預設1.0
2、為什麼在http version為1.0時,lua在開啟檔案時與預期不一致呢?
這個問題暫時沒有得到答案,歡迎大佬留言
本篇完結!