lua-nginx-module icon indicating copy to clipboard operation
lua-nginx-module copied to clipboard

Lua parse json value from request_body

Open xmanag3r opened this issue 2 years ago • 9 comments

Hello, i'm receiving POST to my lua endpoint.

That post body it's with json body.

I need to cut off one object from json post body

The body that is coming is looking like this :

{
    "param1": "1033893",
    "param2": "337483",
    "param3": "test",
    
}

I want to cut only param2 (only numbers) and put it as a value because I need to compare it with one file content

I'm using this local : local check_body = ngx.req.get_body_data()

In bash script I normally run this :

echo $CURL_post_request | cut -d\| -f 1| grep -m1 -oP '\s*"param2"\s*:\s*\K[^,]+'| tr -d '"'| tr -d '}'

But in lua I'm not sure how I can fix this

xmanag3r avatar Mar 02 '23 03:03 xmanag3r

You can just use the lua-cjson library shipped with OpenResty to parse your POST request body in the JSON format.

agentzh avatar Mar 05 '23 22:03 agentzh

Thanks, i've solved that. I have another bug now,

local first_one = 12

string.match(first_one, second_one)

For example let's say first_one is a static variable that I'm entering second_one is a file where it's containing 12 number from file that it's having multiple numbers

local open_file = io.open(filepath, "rb")
   local second_one = open_file:read("*a")

open_file is containing for example

1283813122344
12
12838138931316
128381383131

But I want to get only 12 number (in this case second line) What is the best way to do this?

xmanag3r avatar Mar 05 '23 23:03 xmanag3r

I don't know what exactly you want. Did you want to get the line number in the file? Or did you want to know if the number is in the file? Does the file change?

zhuizhuhaomeng avatar Mar 06 '23 01:03 zhuizhuhaomeng

Hi @zhuizhuhaomeng ,

i want the exact match with the exact of the content to get matched with my actual number .

So please let me know the both options and when i test i will update this issue, so everyone will be aware which one is working for me.

Thanks so much

xmanag3r avatar Mar 06 '23 03:03 xmanag3r

I think you can read the file line by line and use a table to cache the lines if the file content does not change.

zhuizhuhaomeng avatar Mar 06 '23 06:03 zhuizhuhaomeng

Hi @zhuizhuhaomeng

local open_file = io.open(filepath, "rb")
   local second_one = open_file:read("*a")

I'm reading by that, what do you mean line by line, can you give me example?

xmanag3r avatar Mar 06 '23 09:03 xmanag3r

local fh, err = io.open("data.txt")

local cache = {}
if fh == nil then
    -- 
    return
end

for line in fh:lines()
do
    cache[line] = 1
end

Something like the above. It would help if you gave a minimal example to show what you want. Otherwise, we don't know what exactly you want.

zhuizhuhaomeng avatar Mar 06 '23 09:03 zhuizhuhaomeng

So here is my scenario :

I have nginx-lua config, that it contains json data (from POST request) :

{
    "profile_name": "test",
    "number_from_json": "12",
}

In my /opt/file1.csv

1283813122344
12
12838138931316
128381383131

I have

So I'm having this config

location /reader_x {
   proxy_set_header X-Forwarded-Host $host;
   proxy_set_header X-Forwarded-Server $host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Url-Scheme $scheme;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_host;
   proxy_redirect off;
   proxy_pass_request_body on;
   proxy_pass_request_headers on;
   proxy_ssl_verify off;
   if ($request_method = POST ) {
   rewrite_by_lua '
   ngx.req.read_body()
   local check_body = ngx.req.get_body_data()
   local data = ngx.req.get_body_data()
   json = require "dkjson"
   local json_parse = json.decode(check_body)
   local number_cut = json_parse.number_from_json
   local filepath = "/opt/file1.csv"
   local open_file = io.open(filepath, "rb")
   local second_one = open_file:read("*a")
   io.close(open_file)
   local  match0 = string.match(second_one, number_cut)
   if match0 then
   ngx.say("this is exactly matched 12")
else
   ngx.say("not matching")
   end
   ';
proxy_pass https://localhost:8421 ;

So I need only to match 12 unique number, not if the other numbers are contains "12"

Let me know if you need more info

xmanag3r avatar Mar 06 '23 10:03 xmanag3r

Just like what I said above, you need to read the content from the file and cache the result if it is possible. If you open the file and read from the file every time, the disk IO would become a bottleneck.

If the content change from time to time, you want to match the file content you need to use ngx.re: eg:

local m, err = ngx.re.match(second_one, [[\b12\b]], "jo")
if m ~= nil then
    ngx.say("match")
end

zhuizhuhaomeng avatar Mar 07 '23 01:03 zhuizhuhaomeng