How to get post parameters from http request in lu

2019-03-04 10:10发布

问题:

I sent this HTTP POST request via Tasker (Android app) to my NodeMCU, which looks like this:

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Tasker/4.9u4m (Android/6.0.1)
Connection: close
Content-Length: 10
Host: 192.168.0.22
Accept-Encoding: gzip

<action>Play</action><SetVolume>5</SetVolume>

I only want to extract what is between the "<action>" and "<SetVolume>" parameters. How can I do that?

回答1:

For the sake of completeness, here is another solution I came up with:

string.gsub(request, "<(%a+)>([^<]+)</%a+>", function(key, val)
  print(key .. ": " .. val)
end)

A working example using the given HTTP request in your question can be seen here:

https://repl.it/repls/GlamorousAnnualConferences



回答2:

This function allows you to extract text from between two string delimiters:

function get_text (str, init, term)
   local _, start = string.find(str, init)
   local stop = string.find(str, term)
   local result = nil
   if _ and stop then
      result = string.sub(str, start + 1, stop - 1)
   end
   return result
end

Sample interaction:

> msg = "<action>Play</action><SetVolume>5</SetVolume>"
> get_text(msg, "<action>", "<SetVolume>")
Play</action>
> get_text(msg, "<action>", "</SetVolume>")
Play</action><SetVolume>5

This is a modification of the above function that allows nil for either of the parameters init or term. If init is nil, then text is extracted up to the term delimiter. If term is nil, then text is extracted from after init to the end of the string.

function get_text (str, init, term)
   local _, start
   local stop = (term and string.find(str, term)) or 0
   local result = nil
   if init then
      _, start = string.find(str, init)
   else
      _, start = 1, 0
   end

   if _ and stop then
      result = string.sub(str, start + 1, stop - 1)
   end
   return result
end

Sample interaction:

> msg = "<action>Play</action><SetVolume>5</SetVolume>"
> get_text(msg)
<action>Play</action><SetVolume>5</SetVolume>
> get_text(msg, nil, '<SetVolume>')
<action>Play</action>
> get_text(msg, '</action>')
<SetVolume>5</SetVolume>
> get_text(msg, '<action>', '<SetVolume>')
Play</action>