lua and io.read

Posted by Jayveesea on Thu 18 Aug 2011 03:02 AM — 8 posts, 31,101 views.

#0
i have been going through this info posted about using lua on a server... http://www.gammon.com.au/forum/?id=6498 ...but i am having difficulty with the POST method. it seems to hang at the point where the POST data is retrieved via io.read. here is an excerpt from the "cgiutils.lua" portion...

-----begin-----
local post_length = tonumber (os.getenv ("CONTENT_LENGTH")) or 0
if os.getenv ("REQUEST_METHOD") == "POST" and post_length > 0 then
for _, v in ipairs (split (io.read (post_length), "&")) do
assemble_value (v, post_data)
end -- for
end -- if post
------end------

is there any trick when using io.read? did i miss something?

Australia Forum Administrator #1
Did you read the notes on page 2 of that thread about sending:


  print ("Connection: close")


?
#2
i did not see that... so i gave it a try, but no luck.

i also got a response here... http://forum.luahub.com/index.php?topic=3184.0
...this worked for me, so i adapted it to cgiutils.lua, although i do not see that it is any different (besides being its own function.


-- get the post data from form
function getpost()
  
  local post_data={}
  
  local post_length = tonumber (os.getenv ("CONTENT_LENGTH")) or 0
  if os.getenv ("REQUEST_METHOD") == "POST" and post_length > 0 then
    
        local n = tonumber(os.getenv("CONTENT_LENGTH"))
	
	local post=io.read(n)
	
	for _, v in ipairs (split (post, "&")) do
          assemble_value (v, post_data)
        end -- for
	
  end -- if
  
  return post_data
  
end -- getpost
Australia Forum Administrator #3
What you posted on the other forum, namely:


 while io.stdin:read("*line") do
    g = io.stdin:read("*all")
  end


is not what you had (or I had) in the cgiutils.lua.

Are you using cgiutils.lua exactly as posted in my other thread? If not, can you post your entire modified version please? The change you made indeed doesn't seem very different, except that you are doing os.getenv ("CONTENT_LENGTH") twice, which shouldn't make any difference.
#4
what i had posted there was a simple script i was trying to get to work... i had narrowed the problem down to the part in cgiutils.lua where "io.read ("*a")" was happening for a POST retrieval... so i started experimenting with other syntax to see if it would work.

so here is what i had that would not work...

with this page...
#! /usr/bin/lua

dofile "cgiutils.lua"

-- HTTP header
print [[
Content-Type: text/html; charset=iso-8859-1

]]

-- body of page

-- XML header, doctype, page header

print [[
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head> 
<title>My title</title>
</head>
<body>
]]

--- form test

print [[
<form METHOD="post" ACTION=http://10.0.0.2/cgi-bin/test4.lua?humphrey=bogart>
<p>Enter data here: <input type=text Name="Widget" size=20 maxlength=20>
<input Type=hidden Name=date Value="2006-04-28">
<input Type=hidden Name=action Value=fubar>
<input Type=submit Name=Submit Value="Submit">
</p>
</form>
]]

---- end form test

get_data, cookie_data, post_data, request_method = get_user_input ()

print "<h1>GET data</h1>\n"
show_table (get_data)

print "<h1>COOKIE data</h1>\n"
show_table (cookie_data)

print "<h1>POST data</h1>\n"
show_table (post_data)

print ("<p>Request method = ", request_method, "</p>")

-- end of body

print [[
</body>
</html>
]]

#5
...and i can not post the cgiutils.lua because i am hitting a 6000 char max (even with header removed)... but it is the final version on page1 of http://www.gammon.com.au/forum/bbshowpost.php?id=6498&page=1 with the modifications you pointed out from page 2.

also, it appears that mongoose server does not use PATH_INFO, so that part of
cgiutils does not work for me... as of right now i just comment that part out.

Australia Forum Administrator #6
The post on the other thread that starts "Below is the improved cgiutils.lua file." has the corrected version, that uses this:


local post_length = tonumber(os.getenv("CONTENT_LENGTH"))


The earlier version (when I was experimenting) used:


POST_DATA = io.read ("*a")  -- read all of stdin


... which, as you found, can hang because it is trying to read "all data" without knowing how much all is.
#7
i tried both methods, both would hang when using the mongoose server.