ESI清漆不一樣的iframe或鏈接標籤在工作中的一個瀏覽器,它不連接到您提供的任何網址。 ESI只是在清漆內啓動一個新的請求,並通過工作流程(vcl_recv等)。
你期望varnish的行爲像一個http客戶端,解析url,設置授權頭,設置一個主機頭爲api.dev:8081並啓動一個新的http連接/請求,它不會。在這種情況下,我猜想它會啓動一個新的req,將req.url設置爲/app.php/next,繼承父資源(包含esi標記)的請求中的標頭,或者可能完全忽略esi標記。
來完成你想做的事情的方式是(在vcl_recv):
if (req.esi_level > 0 && req.url == "/app.php/next") {
set req.http.Authorization = "BASIC [base64 encoded admin:adminpass]"
return (pass);
}
然後ESI標記看起來應該<esi:include src="/app.php/next" />
如果您需要ESI要求打一個不同的後端服務器,則需要到該服務器添加爲不同的命名後端:
backend authorization_needed {
.host = "api.dev";
.port = "8081";
}
和vcl_recv,告訴清漆用它來ESI要求:
if (req.esi_level > 0 && req.url == "/app.php/next") {
set req.http.Authorization = "BASIC [base64 encoded admin:adminpass]"
set req.backend = authorization_needed;
return (pass);
}
您可能還需要設置req.http.Host,如果後端響應的虛擬主機不是「api.dev」則阻止。
更新:
由於基本授權從客戶端來了,你在呼喚回報(通)時req.http.Authorization存在,清漆不會ESI過程的頁面。您必須在vcl_fetch()中明確啓用esi,而通過時不會調用它。
所以要通過授權的ESI片段而不是父頁面,改變vcl_rev:
if (req.http.Authorization && req.esi_level == 0) {
set req.http.X-Esi-Authorization = req.http.Authorization;
unset req.http.Authorization;
}
else if (req.http.X-Esi-Authorization && req.esi_level > 0) {
set req.http.Authorization = req.http.X-Esi-Authorization;
return (pass);
}
,並加入到vcl_fetch:
if (req.http.X-Esi-Authorization) {
set beresp.do_esi = true;
}
的淨效應是父母響應可緩存並將處理esi,esi片段本身將始終通過客戶端的授權標頭傳遞到後端。
你好,謝謝你的回答。如果我試圖在標記中這樣做,那是因爲用戶和密碼會有_many_用戶和密碼用於同一個URL。所以,我不能直接在Varnish的conf中設置它。那麼,你認爲不可能做到這一點? –
Peekmo
這是一個非常典型的用例。我已經更新了答案。 –
非常感謝!有用 ! – Peekmo