Я использую nginx (и OpenResty) и пытаюсь хешировать $ request_body
для целей кеширования (с srcache ).
При попытке просто echo
$ request_body
он работает безупречно:
# actually echoes the request body
location /works {
# force loading the body
echo_read_request_body;
echo $request_body;
}
Но при попытке вычислить md5 я получаю MD5 для пустой строки, хотя я убедитесь, что $ request_body
загружается через echo_read_request_body;
.
# echoes d41d8cd98f00b204e9800998ecf8427e, which is the MD5 for empty input.
location /doesnt-work-md5 {
# force loading the body
echo_read_request_body;
set_md5 $digest $request_body;
echo $digest;
}
Самым странным явлением является то, что он не работает даже при попытке скопировать переменную:
# echoes nothing - empty data
location /doesnt-work {
# force loading the body
echo_read_request_body;
set $temp $request_body;
echo $temp;
}
Между прочим, эти последние фрагменты не работают при использовании $ echo_request_body
вместо $ request_body
.
Заранее спасибо!
Met die hulp van die ontwikkelaars van OpenResty, besef ek dat die set_XYZ
(dws stel
, set_md5
) word tydens nginx se herskryf
fase geëvalueer, terwyl die $ request_body
/ $ echo_request_body
slegs beskikbaar is deur die inhoud
fase.
Dus, by die evaluering van set_md5 $ digest $ request_body;
, $ request_body
veranderlike is leeg, wat die konstante MD5-resultaat verklaar.
Uiteindelik implementeer ek die werklike generering van die sleutel van die sleutel in my eie API-toepassing (sien onderstaande voorbeeld) en toegang daartoe verkry met access_by_lua
blok.
Die blok loop in die toegang
fase, voor srcache_fetch
en srcache_store
word geëvalueer (hulle evalueer onderskeidelik in post-access
en output-filter
).
Die implementering daarvan in my eie API het groter beheer oor die logiese logika vir die generering van cache moontlik gemaak, wat moeilik sou wees om met nginx alleen te doen (aangesien ek nie 'n volwaardige lua-programmeerder wou word nie).
Ek wou byvoorbeeld in staat wees om deterministies cache
versoeke met Json-liggame te plaas. Json-serialisasie is nie deterministies nie, aangesien sleutels in enige volgorde kan wees. In my API sorteer ek die sleutels sodat die gegenereerde cache-sleutel konstant is vir dieselfde data.
Dit het ook die hantering van die $ request_body
vereenvoudig, aangesien die lua-uitgereikte subvrag dit net aanstuur na die API, ongeag die fase- of skyfbufferstatus.
Die finale opset lyk
location /api {
# proxy_pass ...
# Force normal responses (no deflate, etc.) See https://github.com/openresty/srcache-nginx-module#srcache_ignore_content_encoding
proxy_set_header Accept-Encoding "";
set $cache_key "";
access_by_lua_block {
local res = ngx.location.capture('/generate-key' .. ngx.var.request_uri, {
method=ngx.HTTP_POST,
-- forwards the entire request body,
-- regardless of disk buffering!
always_forward_body=true,
args=ngx.var.args
})
if res then
ngx.var.cache_key = res.body
end
}
# ... srcache options ...
}
location /generate-key {
# proxy_pass ...
}
Voorbeeld van die generering van sleutel-API is soos volg:
import flask
import json
import hashlib
import urllib
app = flask.Flask(__name__)
@app.route('/generate', defaults={'path': ''}, methods=['POST'])
@app.route('/generate/<path:path>', methods=['POST'])
def generate_cache_key(path):
return urllib.quote('{}_{}_{}'.format(path,
digest(stable_body()),
digest(stable_json_dumps(flask.request.args))))
def stable_body():
if flask.request.json:
return stable_json_dumps(flask.request.json)
return flask.request.data
def stable_json_dumps(data):
return json.dumps(data, sort_keys=True)
def digest(data):
return hashlib.md5(data).hexdigest()
if __name__ == '__main__':
app.run()
Я думаю, что у вас проблема с несколькими модулями, работающими в местах, которые вы установили. Однако без остальной части вашей конфигурации я не уверен.
Можете ли вы переместить последний случай в конфигурацию и протестировать?