MD5 $ request_body

Я использую 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 .

Заранее спасибо!

2
задан 25 January 2018 в 00:47
2 ответа

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()
4
ответ дан 3 December 2019 в 10:33

Я думаю, что у вас проблема с несколькими модулями, работающими в местах, которые вы установили. Однако без остальной части вашей конфигурации я не уверен.

Можете ли вы переместить последний случай в конфигурацию и протестировать?

-1
ответ дан 3 December 2019 в 10:33

Теги

Похожие вопросы