1. 程式人生 > 其它 >nginx代理轉發因http_version導致lua讀取檔案不存在問題

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在開啟檔案時與預期不一致呢?

  這個問題暫時沒有得到答案,歡迎大佬留言

本篇完結!